OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
7 #include "sync/internal_api/public/base/model_type_test_util.h" | 7 #include "sync/internal_api/public/base/model_type_test_util.h" |
8 #include "sync/notifier/invalidation_util.h" | 8 #include "sync/notifier/invalidation_util.h" |
9 #include "sync/notifier/mock_ack_handler.h" | 9 #include "sync/notifier/mock_ack_handler.h" |
10 #include "sync/notifier/object_id_invalidation_map.h" | 10 #include "sync/notifier/object_id_invalidation_map.h" |
11 #include "sync/sessions/nudge_tracker.h" | 11 #include "sync/sessions/nudge_tracker.h" |
| 12 #include "sync/test/mock_invalidation.h" |
| 13 #include "sync/test/mock_invalidation_tracker.h" |
| 14 #include "sync/test/trackable_mock_invalidation.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
13 | 16 |
14 namespace syncer { | 17 namespace syncer { |
15 | 18 |
16 namespace { | 19 namespace { |
17 | 20 |
18 testing::AssertionResult ModelTypeSetEquals(ModelTypeSet a, ModelTypeSet b) { | 21 testing::AssertionResult ModelTypeSetEquals(ModelTypeSet a, ModelTypeSet b) { |
19 if (a.Equals(b)) { | 22 if (a.Equals(b)) { |
20 return testing::AssertionSuccess(); | 23 return testing::AssertionSuccess(); |
21 } else { | 24 } else { |
22 return testing::AssertionFailure() | 25 return testing::AssertionFailure() |
23 << "Left side " << ModelTypeSetToString(a) | 26 << "Left side " << ModelTypeSetToString(a) |
24 << ", does not match rigth side: " << ModelTypeSetToString(b); | 27 << ", does not match rigth side: " << ModelTypeSetToString(b); |
25 } | 28 } |
26 } | 29 } |
27 | 30 |
28 syncer::Invalidation BuildUnknownVersionInvalidation(ModelType type) { | |
29 invalidation::ObjectId id; | |
30 bool result = RealModelTypeToObjectId(type, &id); | |
31 DCHECK(result); | |
32 return Invalidation::InitUnknownVersion(id); | |
33 } | |
34 | |
35 | |
36 } // namespace | 31 } // namespace |
37 | 32 |
38 namespace sessions { | 33 namespace sessions { |
39 | 34 |
40 class NudgeTrackerTest : public ::testing::Test { | 35 class NudgeTrackerTest : public ::testing::Test { |
41 public: | 36 public: |
42 NudgeTrackerTest() { | 37 NudgeTrackerTest() { |
43 SetInvalidationsInSync(); | 38 SetInvalidationsInSync(); |
44 } | 39 } |
45 | 40 |
(...skipping 19 matching lines...) Expand all Loading... |
65 sync_pb::GetUpdateTriggers gu_trigger; | 60 sync_pb::GetUpdateTriggers gu_trigger; |
66 nudge_tracker_.FillProtoMessage(type, &gu_trigger); | 61 nudge_tracker_.FillProtoMessage(type, &gu_trigger); |
67 return gu_trigger.datatype_refresh_nudges(); | 62 return gu_trigger.datatype_refresh_nudges(); |
68 } | 63 } |
69 | 64 |
70 void SetInvalidationsInSync() { | 65 void SetInvalidationsInSync() { |
71 nudge_tracker_.OnInvalidationsEnabled(); | 66 nudge_tracker_.OnInvalidationsEnabled(); |
72 nudge_tracker_.RecordSuccessfulSyncCycle(); | 67 nudge_tracker_.RecordSuccessfulSyncCycle(); |
73 } | 68 } |
74 | 69 |
| 70 scoped_ptr<InvalidationInterface> BuildInvalidation( |
| 71 int64 version, |
| 72 const std::string& payload) { |
| 73 return MockInvalidation::Build(version, payload) |
| 74 .PassAs<InvalidationInterface>(); |
| 75 } |
| 76 |
| 77 static scoped_ptr<InvalidationInterface> BuildUnknownVersionInvalidation() { |
| 78 return MockInvalidation::BuildUnknownVersion() |
| 79 .PassAs<InvalidationInterface>(); |
| 80 } |
| 81 |
75 protected: | 82 protected: |
76 NudgeTracker nudge_tracker_; | 83 NudgeTracker nudge_tracker_; |
77 }; | 84 }; |
78 | 85 |
79 // Exercise an empty NudgeTracker. | 86 // Exercise an empty NudgeTracker. |
80 // Use with valgrind to detect uninitialized members. | 87 // Use with valgrind to detect uninitialized members. |
81 TEST_F(NudgeTrackerTest, EmptyNudgeTracker) { | 88 TEST_F(NudgeTrackerTest, EmptyNudgeTracker) { |
82 // Now we're at the normal, "idle" state. | 89 // Now we're at the normal, "idle" state. |
83 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); | 90 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); |
84 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 91 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
(...skipping 27 matching lines...) Expand all Loading... |
112 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); | 119 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); |
113 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, | 120 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, |
114 nudge_tracker_.GetLegacySource()); | 121 nudge_tracker_.GetLegacySource()); |
115 | 122 |
116 // Another local nudge will not be enough to change it. | 123 // Another local nudge will not be enough to change it. |
117 nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); | 124 nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); |
118 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, | 125 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, |
119 nudge_tracker_.GetLegacySource()); | 126 nudge_tracker_.GetLegacySource()); |
120 | 127 |
121 // An invalidation will override the refresh request source. | 128 // An invalidation will override the refresh request source. |
122 ObjectIdInvalidationMap invalidation_map = | 129 nudge_tracker_.RecordRemoteInvalidation(PREFERENCES, |
123 BuildInvalidationMap(PREFERENCES, 1, "hint"); | 130 BuildInvalidation(1, "hint")); |
124 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
125 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, | 131 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, |
126 nudge_tracker_.GetLegacySource()); | 132 nudge_tracker_.GetLegacySource()); |
127 | 133 |
128 // Neither local nudges nor refresh requests will override it. | 134 // Neither local nudges nor refresh requests will override it. |
129 nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); | 135 nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); |
130 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, | 136 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, |
131 nudge_tracker_.GetLegacySource()); | 137 nudge_tracker_.GetLegacySource()); |
132 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); | 138 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); |
133 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, | 139 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, |
134 nudge_tracker_.GetLegacySource()); | 140 nudge_tracker_.GetLegacySource()); |
135 } | 141 } |
136 | 142 |
137 // Verifies the management of invalidation hints and GU trigger fields. | 143 // Verifies the management of invalidation hints and GU trigger fields. |
138 TEST_F(NudgeTrackerTest, HintCoalescing) { | 144 TEST_F(NudgeTrackerTest, HintCoalescing) { |
139 // Easy case: record one hint. | 145 // Easy case: record one hint. |
140 { | 146 { |
141 ObjectIdInvalidationMap invalidation_map = | 147 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
142 BuildInvalidationMap(BOOKMARKS, 1, "bm_hint_1"); | 148 BuildInvalidation(1, "bm_hint_1")); |
143 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
144 | 149 |
145 sync_pb::GetUpdateTriggers gu_trigger; | 150 sync_pb::GetUpdateTriggers gu_trigger; |
146 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 151 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
147 ASSERT_EQ(1, gu_trigger.notification_hint_size()); | 152 ASSERT_EQ(1, gu_trigger.notification_hint_size()); |
148 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0)); | 153 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0)); |
149 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 154 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
150 } | 155 } |
151 | 156 |
152 // Record a second hint for the same type. | 157 // Record a second hint for the same type. |
153 { | 158 { |
154 ObjectIdInvalidationMap invalidation_map = | 159 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
155 BuildInvalidationMap(BOOKMARKS, 2, "bm_hint_2"); | 160 BuildInvalidation(2, "bm_hint_2")); |
156 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
157 | 161 |
158 sync_pb::GetUpdateTriggers gu_trigger; | 162 sync_pb::GetUpdateTriggers gu_trigger; |
159 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 163 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
160 ASSERT_EQ(2, gu_trigger.notification_hint_size()); | 164 ASSERT_EQ(2, gu_trigger.notification_hint_size()); |
161 | 165 |
162 // Expect the most hint recent is last in the list. | 166 // Expect the most hint recent is last in the list. |
163 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0)); | 167 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0)); |
164 EXPECT_EQ("bm_hint_2", gu_trigger.notification_hint(1)); | 168 EXPECT_EQ("bm_hint_2", gu_trigger.notification_hint(1)); |
165 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 169 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
166 } | 170 } |
167 | 171 |
168 // Record a hint for a different type. | 172 // Record a hint for a different type. |
169 { | 173 { |
170 ObjectIdInvalidationMap invalidation_map = | 174 nudge_tracker_.RecordRemoteInvalidation(PASSWORDS, |
171 BuildInvalidationMap(PASSWORDS, 1, "pw_hint_1"); | 175 BuildInvalidation(1, "pw_hint_1")); |
172 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
173 | 176 |
174 // Re-verify the bookmarks to make sure they're unaffected. | 177 // Re-verify the bookmarks to make sure they're unaffected. |
175 sync_pb::GetUpdateTriggers bm_gu_trigger; | 178 sync_pb::GetUpdateTriggers bm_gu_trigger; |
176 nudge_tracker_.FillProtoMessage(BOOKMARKS, &bm_gu_trigger); | 179 nudge_tracker_.FillProtoMessage(BOOKMARKS, &bm_gu_trigger); |
177 ASSERT_EQ(2, bm_gu_trigger.notification_hint_size()); | 180 ASSERT_EQ(2, bm_gu_trigger.notification_hint_size()); |
178 EXPECT_EQ("bm_hint_1", bm_gu_trigger.notification_hint(0)); | 181 EXPECT_EQ("bm_hint_1", bm_gu_trigger.notification_hint(0)); |
179 EXPECT_EQ("bm_hint_2", | 182 EXPECT_EQ("bm_hint_2", |
180 bm_gu_trigger.notification_hint(1)); // most recent last. | 183 bm_gu_trigger.notification_hint(1)); // most recent last. |
181 EXPECT_FALSE(bm_gu_trigger.client_dropped_hints()); | 184 EXPECT_FALSE(bm_gu_trigger.client_dropped_hints()); |
182 | 185 |
183 // Verify the new type, too. | 186 // Verify the new type, too. |
184 sync_pb::GetUpdateTriggers pw_gu_trigger; | 187 sync_pb::GetUpdateTriggers pw_gu_trigger; |
185 nudge_tracker_.FillProtoMessage(PASSWORDS, &pw_gu_trigger); | 188 nudge_tracker_.FillProtoMessage(PASSWORDS, &pw_gu_trigger); |
186 ASSERT_EQ(1, pw_gu_trigger.notification_hint_size()); | 189 ASSERT_EQ(1, pw_gu_trigger.notification_hint_size()); |
187 EXPECT_EQ("pw_hint_1", pw_gu_trigger.notification_hint(0)); | 190 EXPECT_EQ("pw_hint_1", pw_gu_trigger.notification_hint(0)); |
188 EXPECT_FALSE(pw_gu_trigger.client_dropped_hints()); | 191 EXPECT_FALSE(pw_gu_trigger.client_dropped_hints()); |
189 } | 192 } |
190 } | 193 } |
191 | 194 |
192 // Test the dropping of invalidation hints. Receives invalidations one by one. | 195 // Test the dropping of invalidation hints. Receives invalidations one by one. |
193 TEST_F(NudgeTrackerTest, DropHintsLocally_OneAtATime) { | 196 TEST_F(NudgeTrackerTest, DropHintsLocally_OneAtATime) { |
194 for (size_t i = 0; i < GetHintBufferSize(); ++i) { | 197 for (size_t i = 0; i < GetHintBufferSize(); ++i) { |
195 ObjectIdInvalidationMap invalidation_map = | 198 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
196 BuildInvalidationMap(BOOKMARKS, i, "hint"); | 199 BuildInvalidation(i, "hint")); |
197 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
198 } | 200 } |
199 { | 201 { |
200 sync_pb::GetUpdateTriggers gu_trigger; | 202 sync_pb::GetUpdateTriggers gu_trigger; |
201 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 203 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
202 EXPECT_EQ(GetHintBufferSize(), | 204 EXPECT_EQ(GetHintBufferSize(), |
203 static_cast<size_t>(gu_trigger.notification_hint_size())); | 205 static_cast<size_t>(gu_trigger.notification_hint_size())); |
204 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 206 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
205 } | 207 } |
206 | 208 |
207 // Force an overflow. | 209 // Force an overflow. |
208 ObjectIdInvalidationMap invalidation_map2 = | 210 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
209 BuildInvalidationMap(BOOKMARKS, 1000, "new_hint"); | 211 BuildInvalidation(1000, "new_hint")); |
210 nudge_tracker_.RecordRemoteInvalidation(invalidation_map2); | |
211 | 212 |
212 { | 213 { |
213 sync_pb::GetUpdateTriggers gu_trigger; | 214 sync_pb::GetUpdateTriggers gu_trigger; |
214 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 215 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
215 EXPECT_TRUE(gu_trigger.client_dropped_hints()); | 216 EXPECT_TRUE(gu_trigger.client_dropped_hints()); |
216 ASSERT_EQ(GetHintBufferSize(), | 217 ASSERT_EQ(GetHintBufferSize(), |
217 static_cast<size_t>(gu_trigger.notification_hint_size())); | 218 static_cast<size_t>(gu_trigger.notification_hint_size())); |
218 | 219 |
219 // Verify the newest hint was not dropped and is the last in the list. | 220 // Verify the newest hint was not dropped and is the last in the list. |
220 EXPECT_EQ("new_hint", gu_trigger.notification_hint(GetHintBufferSize()-1)); | 221 EXPECT_EQ("new_hint", gu_trigger.notification_hint(GetHintBufferSize()-1)); |
221 | 222 |
222 // Verify the oldest hint, too. | 223 // Verify the oldest hint, too. |
223 EXPECT_EQ("hint", gu_trigger.notification_hint(0)); | 224 EXPECT_EQ("hint", gu_trigger.notification_hint(0)); |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 // Test the dropping of invalidation hints. | |
228 // Receives invalidations in large batches. | |
229 TEST_F(NudgeTrackerTest, DropHintsLocally_ManyHints) { | |
230 ObjectIdInvalidationMap invalidation_map; | |
231 for (size_t i = 0; i < GetHintBufferSize(); ++i) { | |
232 invalidation_map.Insert(BuildInvalidation(BOOKMARKS, i, "hint")); | |
233 } | |
234 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
235 { | |
236 sync_pb::GetUpdateTriggers gu_trigger; | |
237 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | |
238 EXPECT_EQ(GetHintBufferSize(), | |
239 static_cast<size_t>(gu_trigger.notification_hint_size())); | |
240 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | |
241 } | |
242 | |
243 // Force an overflow. | |
244 ObjectIdInvalidationMap invalidation_map2; | |
245 invalidation_map2.Insert(BuildInvalidation(BOOKMARKS, 1000, "new_hint")); | |
246 invalidation_map2.Insert(BuildInvalidation(BOOKMARKS, 1001, "newer_hint")); | |
247 nudge_tracker_.RecordRemoteInvalidation(invalidation_map2); | |
248 | |
249 { | |
250 sync_pb::GetUpdateTriggers gu_trigger; | |
251 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | |
252 EXPECT_TRUE(gu_trigger.client_dropped_hints()); | |
253 ASSERT_EQ(GetHintBufferSize(), | |
254 static_cast<size_t>(gu_trigger.notification_hint_size())); | |
255 | |
256 // Verify the newest hints were not dropped and are the last in the list. | |
257 EXPECT_EQ("newer_hint", | |
258 gu_trigger.notification_hint(GetHintBufferSize()-1)); | |
259 EXPECT_EQ("new_hint", gu_trigger.notification_hint(GetHintBufferSize()-2)); | |
260 | |
261 // Verify the oldest hint, too. | |
262 EXPECT_EQ("hint", gu_trigger.notification_hint(0)); | |
263 } | |
264 } | |
265 | |
266 // Tests the receipt of 'unknown version' invalidations. | 228 // Tests the receipt of 'unknown version' invalidations. |
267 TEST_F(NudgeTrackerTest, DropHintsAtServer_Alone) { | 229 TEST_F(NudgeTrackerTest, DropHintsAtServer_Alone) { |
268 ObjectIdInvalidationMap invalidation_map; | |
269 invalidation_map.Insert(BuildUnknownVersionInvalidation(BOOKMARKS)); | |
270 | |
271 // Record the unknown version invalidation. | 230 // Record the unknown version invalidation. |
272 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | 231 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
| 232 BuildUnknownVersionInvalidation()); |
273 { | 233 { |
274 sync_pb::GetUpdateTriggers gu_trigger; | 234 sync_pb::GetUpdateTriggers gu_trigger; |
275 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 235 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
276 EXPECT_TRUE(gu_trigger.server_dropped_hints()); | 236 EXPECT_TRUE(gu_trigger.server_dropped_hints()); |
277 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 237 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
278 ASSERT_EQ(0, gu_trigger.notification_hint_size()); | 238 ASSERT_EQ(0, gu_trigger.notification_hint_size()); |
279 } | 239 } |
280 | 240 |
281 // Clear status then verify. | 241 // Clear status then verify. |
282 nudge_tracker_.RecordSuccessfulSyncCycle(); | 242 nudge_tracker_.RecordSuccessfulSyncCycle(); |
283 { | 243 { |
284 sync_pb::GetUpdateTriggers gu_trigger; | 244 sync_pb::GetUpdateTriggers gu_trigger; |
285 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 245 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
286 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 246 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
287 EXPECT_FALSE(gu_trigger.server_dropped_hints()); | 247 EXPECT_FALSE(gu_trigger.server_dropped_hints()); |
288 ASSERT_EQ(0, gu_trigger.notification_hint_size()); | 248 ASSERT_EQ(0, gu_trigger.notification_hint_size()); |
289 } | 249 } |
290 } | 250 } |
291 | 251 |
292 // Tests the receipt of 'unknown version' invalidations. This test also | 252 // Tests the receipt of 'unknown version' invalidations. This test also |
293 // includes a known version invalidation to mix things up a bit. | 253 // includes a known version invalidation to mix things up a bit. |
294 TEST_F(NudgeTrackerTest, DropHintsAtServer_WithOtherInvalidations) { | 254 TEST_F(NudgeTrackerTest, DropHintsAtServer_WithOtherInvalidations) { |
295 ObjectIdInvalidationMap invalidation_map; | 255 // Record the two invalidations, one with unknown version, the other known. |
296 invalidation_map.Insert(BuildUnknownVersionInvalidation(BOOKMARKS)); | 256 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
297 invalidation_map.Insert(BuildInvalidation(BOOKMARKS, 10, "hint")); | 257 BuildUnknownVersionInvalidation()); |
| 258 nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, |
| 259 BuildInvalidation(10, "hint")); |
298 | 260 |
299 // Record the two invalidations, one with unknown version, the other unknown. | |
300 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
301 { | 261 { |
302 sync_pb::GetUpdateTriggers gu_trigger; | 262 sync_pb::GetUpdateTriggers gu_trigger; |
303 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); | 263 nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); |
304 EXPECT_TRUE(gu_trigger.server_dropped_hints()); | 264 EXPECT_TRUE(gu_trigger.server_dropped_hints()); |
305 EXPECT_FALSE(gu_trigger.client_dropped_hints()); | 265 EXPECT_FALSE(gu_trigger.client_dropped_hints()); |
306 ASSERT_EQ(1, gu_trigger.notification_hint_size()); | 266 ASSERT_EQ(1, gu_trigger.notification_hint_size()); |
307 EXPECT_EQ("hint", gu_trigger.notification_hint(0)); | 267 EXPECT_EQ("hint", gu_trigger.notification_hint(0)); |
308 } | 268 } |
309 | 269 |
310 // Clear status then verify. | 270 // Clear status then verify. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 nudge_tracker_.RecordSuccessfulSyncCycle(); | 353 nudge_tracker_.RecordSuccessfulSyncCycle(); |
394 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); | 354 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); |
395 | 355 |
396 // Refresh requests. | 356 // Refresh requests. |
397 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(SESSIONS)); | 357 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(SESSIONS)); |
398 EXPECT_TRUE(nudge_tracker_.IsSyncRequired()); | 358 EXPECT_TRUE(nudge_tracker_.IsSyncRequired()); |
399 nudge_tracker_.RecordSuccessfulSyncCycle(); | 359 nudge_tracker_.RecordSuccessfulSyncCycle(); |
400 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); | 360 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); |
401 | 361 |
402 // Invalidations. | 362 // Invalidations. |
403 ObjectIdInvalidationMap invalidation_map = | 363 nudge_tracker_.RecordRemoteInvalidation(PREFERENCES, |
404 BuildInvalidationMap(PREFERENCES, 1, "hint"); | 364 BuildInvalidation(1, "hint")); |
405 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
406 EXPECT_TRUE(nudge_tracker_.IsSyncRequired()); | 365 EXPECT_TRUE(nudge_tracker_.IsSyncRequired()); |
407 nudge_tracker_.RecordSuccessfulSyncCycle(); | 366 nudge_tracker_.RecordSuccessfulSyncCycle(); |
408 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); | 367 EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); |
409 } | 368 } |
410 | 369 |
411 // Basic tests for the IsGetUpdatesRequired() flag. | 370 // Basic tests for the IsGetUpdatesRequired() flag. |
412 TEST_F(NudgeTrackerTest, IsGetUpdatesRequired) { | 371 TEST_F(NudgeTrackerTest, IsGetUpdatesRequired) { |
413 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 372 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
414 | 373 |
415 // Local changes. | 374 // Local changes. |
416 nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)); | 375 nudge_tracker_.RecordLocalChange(ModelTypeSet(SESSIONS)); |
417 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 376 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
418 nudge_tracker_.RecordSuccessfulSyncCycle(); | 377 nudge_tracker_.RecordSuccessfulSyncCycle(); |
419 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 378 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
420 | 379 |
421 // Refresh requests. | 380 // Refresh requests. |
422 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(SESSIONS)); | 381 nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(SESSIONS)); |
423 EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired()); | 382 EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired()); |
424 nudge_tracker_.RecordSuccessfulSyncCycle(); | 383 nudge_tracker_.RecordSuccessfulSyncCycle(); |
425 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 384 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
426 | 385 |
427 // Invalidations. | 386 // Invalidations. |
428 ObjectIdInvalidationMap invalidation_map = | 387 nudge_tracker_.RecordRemoteInvalidation(PREFERENCES, |
429 BuildInvalidationMap(PREFERENCES, 1, "hint"); | 388 BuildInvalidation(1, "hint")); |
430 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
431 EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired()); | 389 EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired()); |
432 nudge_tracker_.RecordSuccessfulSyncCycle(); | 390 nudge_tracker_.RecordSuccessfulSyncCycle(); |
433 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); | 391 EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); |
434 } | 392 } |
435 | 393 |
436 // Test IsSyncRequired() responds correctly to data type throttling. | 394 // Test IsSyncRequired() responds correctly to data type throttling. |
437 TEST_F(NudgeTrackerTest, IsSyncRequired_Throttling) { | 395 TEST_F(NudgeTrackerTest, IsSyncRequired_Throttling) { |
438 const base::TimeTicks t0 = base::TimeTicks::FromInternalValue(1234); | 396 const base::TimeTicks t0 = base::TimeTicks::FromInternalValue(1234); |
439 const base::TimeDelta throttle_length = base::TimeDelta::FromMinutes(10); | 397 const base::TimeDelta throttle_length = base::TimeDelta::FromMinutes(10); |
440 const base::TimeTicks t1 = t0 + throttle_length; | 398 const base::TimeTicks t1 = t0 + throttle_length; |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 // becomes due. Perform a successful sync cycle to service it. | 695 // becomes due. Perform a successful sync cycle to service it. |
738 nudge_tracker_.SetSyncCycleStartTime(t6); | 696 nudge_tracker_.SetSyncCycleStartTime(t6); |
739 EXPECT_TRUE(nudge_tracker_.IsRetryRequired()); | 697 EXPECT_TRUE(nudge_tracker_.IsRetryRequired()); |
740 nudge_tracker_.RecordSuccessfulSyncCycle(); | 698 nudge_tracker_.RecordSuccessfulSyncCycle(); |
741 } | 699 } |
742 | 700 |
743 class NudgeTrackerAckTrackingTest : public NudgeTrackerTest { | 701 class NudgeTrackerAckTrackingTest : public NudgeTrackerTest { |
744 public: | 702 public: |
745 NudgeTrackerAckTrackingTest() {} | 703 NudgeTrackerAckTrackingTest() {} |
746 | 704 |
747 bool IsInvalidationUnacknowledged(const syncer::Invalidation& invalidation) { | 705 bool IsInvalidationUnacknowledged(int tracking_id) { |
748 // Run pending tasks before checking with the MockAckHandler. | 706 return tracker_.IsUnacked(tracking_id); |
749 // The WeakHandle may have posted some tasks for it. | |
750 base::RunLoop().RunUntilIdle(); | |
751 return mock_ack_handler_.IsUnacked(invalidation); | |
752 } | 707 } |
753 | 708 |
754 bool IsInvalidationAcknowledged(const syncer::Invalidation& invalidation) { | 709 bool IsInvalidationAcknowledged(int tracking_id) { |
755 // Run pending tasks before checking with the MockAckHandler. | 710 return tracker_.IsAcknowledged(tracking_id); |
756 // The WeakHandle may have posted some tasks for it. | |
757 base::RunLoop().RunUntilIdle(); | |
758 return mock_ack_handler_.IsAcknowledged(invalidation); | |
759 } | 711 } |
760 | 712 |
761 bool IsInvalidationDropped(const syncer::Invalidation& invalidation) { | 713 bool IsInvalidationDropped(int tracking_id) { |
762 // Run pending tasks before checking with the MockAckHandler. | 714 return tracker_.IsDropped(tracking_id); |
763 // The WeakHandle may have posted some tasks for it. | |
764 base::RunLoop().RunUntilIdle(); | |
765 return mock_ack_handler_.IsDropped(invalidation); | |
766 } | 715 } |
767 | 716 |
768 bool AllInvalidationsAccountedFor() { | 717 int SendInvalidation(ModelType type, int version, const std::string& hint) { |
769 return mock_ack_handler_.AllInvalidationsAccountedFor(); | 718 // Build and register the invalidation. |
| 719 scoped_ptr<TrackableMockInvalidation> inv = |
| 720 tracker_.IssueInvalidation(version, hint); |
| 721 int id = inv->GetTrackingId(); |
| 722 |
| 723 // Send it to the NudgeTracker. |
| 724 nudge_tracker_.RecordRemoteInvalidation( |
| 725 type, inv.PassAs<InvalidationInterface>()); |
| 726 |
| 727 // Return its ID to the test framework for use in assertions. |
| 728 return id; |
770 } | 729 } |
771 | 730 |
772 Invalidation SendInvalidation( | 731 int SendUnknownVersionInvalidation(ModelType type) { |
773 ModelType type, | |
774 int64 version, | |
775 const std::string& hint) { | |
776 // Build and register the invalidation. | 732 // Build and register the invalidation. |
777 syncer::Invalidation invalidation = BuildInvalidation(type, version, hint); | 733 scoped_ptr<TrackableMockInvalidation> inv = |
778 mock_ack_handler_.RegisterInvalidation(&invalidation); | 734 tracker_.IssueUnknownVersionInvalidation(); |
| 735 int id = inv->GetTrackingId(); |
779 | 736 |
780 // Send it to the NudgeTracker. | 737 // Send it to the NudgeTracker. |
781 ObjectIdInvalidationMap invalidation_map; | 738 nudge_tracker_.RecordRemoteInvalidation( |
782 invalidation_map.Insert(invalidation); | 739 type, inv.PassAs<InvalidationInterface>()); |
783 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
784 | 740 |
785 // Return it to the test framework for use in assertions. | 741 // Return its ID to the test framework for use in assertions. |
786 return invalidation; | 742 return id; |
787 } | 743 } |
788 | 744 |
789 Invalidation SendUnknownVersionInvalidation(ModelType type) { | 745 bool AllInvalidationsAccountedFor() const { |
790 // Build and register the invalidation. | 746 return tracker_.AllInvalidationsAccountedFor(); |
791 syncer::Invalidation invalidation = BuildUnknownVersionInvalidation(type); | |
792 mock_ack_handler_.RegisterInvalidation(&invalidation); | |
793 | |
794 // Send it to the NudgeTracker. | |
795 ObjectIdInvalidationMap invalidation_map; | |
796 invalidation_map.Insert(invalidation); | |
797 nudge_tracker_.RecordRemoteInvalidation(invalidation_map); | |
798 | |
799 // Return it to the test framework for use in assertions. | |
800 return invalidation; | |
801 } | 747 } |
802 | 748 |
803 void RecordSuccessfulSyncCycle() { | 749 void RecordSuccessfulSyncCycle() { |
804 nudge_tracker_.RecordSuccessfulSyncCycle(); | 750 nudge_tracker_.RecordSuccessfulSyncCycle(); |
805 } | 751 } |
806 | 752 |
807 private: | 753 private: |
808 syncer::MockAckHandler mock_ack_handler_; | 754 MockInvalidationTracker tracker_; |
809 base::MessageLoop loop_; | |
810 }; | 755 }; |
811 | 756 |
812 // Test the acknowledgement of a single invalidation. | 757 // Test the acknowledgement of a single invalidation. |
813 TEST_F(NudgeTrackerAckTrackingTest, SimpleAcknowledgement) { | 758 TEST_F(NudgeTrackerAckTrackingTest, SimpleAcknowledgement) { |
814 Invalidation inv = SendInvalidation(BOOKMARKS, 10, "hint"); | 759 int inv_id = SendInvalidation(BOOKMARKS, 10, "hint"); |
815 | 760 |
816 EXPECT_TRUE(IsInvalidationUnacknowledged(inv)); | 761 EXPECT_TRUE(IsInvalidationUnacknowledged(inv_id)); |
817 | 762 |
818 RecordSuccessfulSyncCycle(); | 763 RecordSuccessfulSyncCycle(); |
819 EXPECT_TRUE(IsInvalidationAcknowledged(inv)); | 764 EXPECT_TRUE(IsInvalidationAcknowledged(inv_id)); |
820 | 765 |
821 EXPECT_TRUE(AllInvalidationsAccountedFor()); | 766 EXPECT_TRUE(AllInvalidationsAccountedFor()); |
822 } | 767 } |
823 | 768 |
824 // Test the acknowledgement of many invalidations. | 769 // Test the acknowledgement of many invalidations. |
825 TEST_F(NudgeTrackerAckTrackingTest, ManyAcknowledgements) { | 770 TEST_F(NudgeTrackerAckTrackingTest, ManyAcknowledgements) { |
826 Invalidation inv1 = SendInvalidation(BOOKMARKS, 10, "hint"); | 771 int inv1_id = SendInvalidation(BOOKMARKS, 10, "hint"); |
827 Invalidation inv2 = SendInvalidation(BOOKMARKS, 14, "hint2"); | 772 int inv2_id = SendInvalidation(BOOKMARKS, 14, "hint2"); |
828 Invalidation inv3 = SendInvalidation(PREFERENCES, 8, "hint3"); | 773 int inv3_id = SendInvalidation(PREFERENCES, 8, "hint3"); |
829 | 774 |
830 EXPECT_TRUE(IsInvalidationUnacknowledged(inv1)); | 775 EXPECT_TRUE(IsInvalidationUnacknowledged(inv1_id)); |
831 EXPECT_TRUE(IsInvalidationUnacknowledged(inv2)); | 776 EXPECT_TRUE(IsInvalidationUnacknowledged(inv2_id)); |
832 EXPECT_TRUE(IsInvalidationUnacknowledged(inv3)); | 777 EXPECT_TRUE(IsInvalidationUnacknowledged(inv3_id)); |
833 | 778 |
834 RecordSuccessfulSyncCycle(); | 779 RecordSuccessfulSyncCycle(); |
835 EXPECT_TRUE(IsInvalidationAcknowledged(inv1)); | 780 EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id)); |
836 EXPECT_TRUE(IsInvalidationAcknowledged(inv2)); | 781 EXPECT_TRUE(IsInvalidationAcknowledged(inv2_id)); |
837 EXPECT_TRUE(IsInvalidationAcknowledged(inv3)); | 782 EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id)); |
838 | 783 |
839 EXPECT_TRUE(AllInvalidationsAccountedFor()); | 784 EXPECT_TRUE(AllInvalidationsAccountedFor()); |
840 } | 785 } |
841 | 786 |
842 // Test dropping when the buffer overflows and subsequent drop recovery. | 787 // Test dropping when the buffer overflows and subsequent drop recovery. |
843 TEST_F(NudgeTrackerAckTrackingTest, OverflowAndRecover) { | 788 TEST_F(NudgeTrackerAckTrackingTest, OverflowAndRecover) { |
844 std::vector<Invalidation> invalidations; | 789 std::vector<int> invalidation_ids; |
845 | 790 |
846 Invalidation inv10 = SendInvalidation(BOOKMARKS, 10, "hint"); | 791 int inv10_id = SendInvalidation(BOOKMARKS, 10, "hint"); |
847 for (size_t i = 1; i < GetHintBufferSize(); ++i) { | 792 for (size_t i = 1; i < GetHintBufferSize(); ++i) { |
848 invalidations.push_back(SendInvalidation(BOOKMARKS, i+10, "hint")); | 793 invalidation_ids.push_back(SendInvalidation(BOOKMARKS, i + 10, "hint")); |
849 } | 794 } |
850 | 795 |
851 for (std::vector<Invalidation>::iterator it = invalidations.begin(); | 796 for (std::vector<int>::iterator it = invalidation_ids.begin(); |
852 it != invalidations.end(); ++it) { | 797 it != invalidation_ids.end(); |
| 798 ++it) { |
853 EXPECT_TRUE(IsInvalidationUnacknowledged(*it)); | 799 EXPECT_TRUE(IsInvalidationUnacknowledged(*it)); |
854 } | 800 } |
855 | 801 |
856 // This invalidation, though arriving the most recently, has the oldest | 802 // This invalidation, though arriving the most recently, has the oldest |
857 // version number so it should be dropped first. | 803 // version number so it should be dropped first. |
858 Invalidation inv5 = SendInvalidation(BOOKMARKS, 5, "old_hint"); | 804 int inv5_id = SendInvalidation(BOOKMARKS, 5, "old_hint"); |
859 EXPECT_TRUE(IsInvalidationDropped(inv5)); | 805 EXPECT_TRUE(IsInvalidationDropped(inv5_id)); |
860 | 806 |
861 // This invalidation has a larger version number, so it will force a | 807 // This invalidation has a larger version number, so it will force a |
862 // previously delivered invalidation to be dropped. | 808 // previously delivered invalidation to be dropped. |
863 Invalidation inv100 = SendInvalidation(BOOKMARKS, 100, "new_hint"); | 809 int inv100_id = SendInvalidation(BOOKMARKS, 100, "new_hint"); |
864 EXPECT_TRUE(IsInvalidationDropped(inv10)); | 810 EXPECT_TRUE(IsInvalidationDropped(inv10_id)); |
865 | 811 |
866 // This should recover from the drop and bring us back into sync. | 812 // This should recover from the drop and bring us back into sync. |
867 RecordSuccessfulSyncCycle(); | 813 RecordSuccessfulSyncCycle(); |
868 | 814 |
869 for (std::vector<Invalidation>::iterator it = invalidations.begin(); | 815 for (std::vector<int>::iterator it = invalidation_ids.begin(); |
870 it != invalidations.end(); ++it) { | 816 it != invalidation_ids.end(); |
| 817 ++it) { |
871 EXPECT_TRUE(IsInvalidationAcknowledged(*it)); | 818 EXPECT_TRUE(IsInvalidationAcknowledged(*it)); |
872 } | 819 } |
873 EXPECT_TRUE(IsInvalidationAcknowledged(inv100)); | 820 EXPECT_TRUE(IsInvalidationAcknowledged(inv100_id)); |
874 | 821 |
875 EXPECT_TRUE(AllInvalidationsAccountedFor()); | 822 EXPECT_TRUE(AllInvalidationsAccountedFor()); |
876 } | 823 } |
877 | 824 |
878 // Test receipt of an unknown version invalidation from the server. | 825 // Test receipt of an unknown version invalidation from the server. |
879 TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Simple) { | 826 TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Simple) { |
880 Invalidation inv = SendUnknownVersionInvalidation(BOOKMARKS); | 827 int inv_id = SendUnknownVersionInvalidation(BOOKMARKS); |
881 EXPECT_TRUE(IsInvalidationUnacknowledged(inv)); | 828 EXPECT_TRUE(IsInvalidationUnacknowledged(inv_id)); |
882 RecordSuccessfulSyncCycle(); | 829 RecordSuccessfulSyncCycle(); |
883 EXPECT_TRUE(IsInvalidationAcknowledged(inv)); | 830 EXPECT_TRUE(IsInvalidationAcknowledged(inv_id)); |
884 EXPECT_TRUE(AllInvalidationsAccountedFor()); | 831 EXPECT_TRUE(AllInvalidationsAccountedFor()); |
885 } | 832 } |
886 | 833 |
887 // Test receipt of multiple unknown version invalidations from the server. | 834 // Test receipt of multiple unknown version invalidations from the server. |
888 TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Complex) { | 835 TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Complex) { |
889 Invalidation inv1 = SendUnknownVersionInvalidation(BOOKMARKS); | 836 int inv1_id = SendUnknownVersionInvalidation(BOOKMARKS); |
890 Invalidation inv2 = SendInvalidation(BOOKMARKS, 10, "hint"); | 837 int inv2_id = SendInvalidation(BOOKMARKS, 10, "hint"); |
891 Invalidation inv3 = SendUnknownVersionInvalidation(BOOKMARKS); | 838 int inv3_id = SendUnknownVersionInvalidation(BOOKMARKS); |
892 Invalidation inv4 = SendUnknownVersionInvalidation(BOOKMARKS); | 839 int inv4_id = SendUnknownVersionInvalidation(BOOKMARKS); |
893 Invalidation inv5 = SendInvalidation(BOOKMARKS, 20, "hint2"); | 840 int inv5_id = SendInvalidation(BOOKMARKS, 20, "hint2"); |
894 | 841 |
895 // These invalidations have been overridden, so they got acked early. | 842 // These invalidations have been overridden, so they got acked early. |
896 EXPECT_TRUE(IsInvalidationAcknowledged(inv1)); | 843 EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id)); |
897 EXPECT_TRUE(IsInvalidationAcknowledged(inv3)); | 844 EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id)); |
898 | 845 |
899 // These invalidations are still waiting to be used. | 846 // These invalidations are still waiting to be used. |
900 EXPECT_TRUE(IsInvalidationUnacknowledged(inv2)); | 847 EXPECT_TRUE(IsInvalidationUnacknowledged(inv2_id)); |
901 EXPECT_TRUE(IsInvalidationUnacknowledged(inv4)); | 848 EXPECT_TRUE(IsInvalidationUnacknowledged(inv4_id)); |
902 EXPECT_TRUE(IsInvalidationUnacknowledged(inv5)); | 849 EXPECT_TRUE(IsInvalidationUnacknowledged(inv5_id)); |
903 | 850 |
904 // Finish the sync cycle and expect all remaining invalidations to be acked. | 851 // Finish the sync cycle and expect all remaining invalidations to be acked. |
905 RecordSuccessfulSyncCycle(); | 852 RecordSuccessfulSyncCycle(); |
906 EXPECT_TRUE(IsInvalidationAcknowledged(inv1)); | 853 EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id)); |
907 EXPECT_TRUE(IsInvalidationAcknowledged(inv2)); | 854 EXPECT_TRUE(IsInvalidationAcknowledged(inv2_id)); |
908 EXPECT_TRUE(IsInvalidationAcknowledged(inv3)); | 855 EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id)); |
909 EXPECT_TRUE(IsInvalidationAcknowledged(inv4)); | 856 EXPECT_TRUE(IsInvalidationAcknowledged(inv4_id)); |
910 EXPECT_TRUE(IsInvalidationAcknowledged(inv5)); | 857 EXPECT_TRUE(IsInvalidationAcknowledged(inv5_id)); |
911 | 858 |
912 EXPECT_TRUE(AllInvalidationsAccountedFor()); | 859 EXPECT_TRUE(AllInvalidationsAccountedFor()); |
913 } | 860 } |
914 | 861 |
915 } // namespace sessions | 862 } // namespace sessions |
916 } // namespace syncer | 863 } // namespace syncer |
OLD | NEW |