Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: sync/sessions/nudge_tracker_unittest.cc

Issue 14963002: sync: Report GetUpdate triggers to the server (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update tests Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "sync/sessions/nudge_tracker.h" 5 #include "sync/sessions/nudge_tracker.h"
6 6
7 #include "sync/internal_api/public/base/model_type_invalidation_map.h" 7 #include "sync/internal_api/public/base/model_type_invalidation_map.h"
8 #include "sync/internal_api/public/sessions/sync_source_info.h"
8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
9 10
10 namespace syncer { 11 namespace syncer {
11 12
12 namespace { 13 namespace {
13 14
14 ModelTypeSet ParamsMeaningAllEnabledTypes() { 15 testing::AssertionResult ModelTypeSetEquals(ModelTypeSet a, ModelTypeSet b) {
15 ModelTypeSet request_params(BOOKMARKS, AUTOFILL); 16 if (a.Equals(b)) {
16 return request_params; 17 return testing::AssertionSuccess();
17 } 18 } else {
18 19 return testing::AssertionFailure()
19 ModelTypeSet ParamsMeaningJustOneEnabledType() { 20 << "Left side " << ModelTypeSetToString(a)
20 return ModelTypeSet(AUTOFILL); 21 << ", does not match rigth side: " << ModelTypeSetToString(b);
22 }
21 } 23 }
22 24
23 } // namespace 25 } // namespace
24 26
25 namespace sessions { 27 namespace sessions {
26 28
27 TEST(NudgeTrackerTest, CoalesceSources) { 29 class NudgeTrackerTest : public ::testing::Test {
28 ModelTypeInvalidationMap one_type = 30 public:
29 ModelTypeSetToInvalidationMap( 31 static size_t GetHintBufferSize() {
30 ParamsMeaningJustOneEnabledType(), 32 return NudgeTracker::kMaxPayloadsPerType;
31 std::string()); 33 }
32 ModelTypeInvalidationMap all_types = 34
33 ModelTypeSetToInvalidationMap( 35 bool InvalidationsOutOfSync(const NudgeTracker& nudge_tracker) {
34 ParamsMeaningAllEnabledTypes(), 36 // We don't currently track invalidations out of sync on a per-type basis.
35 std::string()); 37 sync_pb::GetUpdateTriggers gu_trigger;
36 sessions::SyncSourceInfo source_one( 38 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
37 sync_pb::GetUpdatesCallerInfo::NOTIFICATION, one_type); 39 return gu_trigger.invalidations_out_of_sync();
38 sessions::SyncSourceInfo source_two( 40 }
39 sync_pb::GetUpdatesCallerInfo::LOCAL, all_types); 41
40 42 int ProtoLocallyModifiedCount(const NudgeTracker& nudge_tracker,
41 NudgeTracker tracker; 43 ModelType type) {
42 EXPECT_TRUE(tracker.IsEmpty()); 44 sync_pb::GetUpdateTriggers gu_trigger;
43 45 nudge_tracker.FillProtoMessage(type, &gu_trigger);
44 tracker.CoalesceSources(source_one); 46 return gu_trigger.local_modification_nudges();
45 EXPECT_EQ(source_one.updates_source, tracker.source_info().updates_source); 47 }
46 48
47 tracker.CoalesceSources(source_two); 49 int ProtoRefreshRequestedCount(const NudgeTracker& nudge_tracker,
48 EXPECT_EQ(source_two.updates_source, tracker.source_info().updates_source); 50 ModelType type) {
49 } 51 sync_pb::GetUpdateTriggers gu_trigger;
50 52 nudge_tracker.FillProtoMessage(type, &gu_trigger);
51 TEST(NudgeTrackerTest, LocallyModifiedTypes_WithInvalidationFirst) { 53 return gu_trigger.datatype_refresh_nudges();
52 ModelTypeInvalidationMap one_type = 54 }
53 ModelTypeSetToInvalidationMap( 55 };
54 ParamsMeaningJustOneEnabledType(), 56
55 std::string()); 57 // Exercise an empty NudgeTracker.
56 ModelTypeInvalidationMap all_types = 58 // Use with valgrind to detect uninitialized members.
57 ModelTypeSetToInvalidationMap( 59 TEST_F(NudgeTrackerTest, EmptyNudgeTracker) {
58 ParamsMeaningAllEnabledTypes(), 60 NudgeTracker nudge_tracker;
59 std::string()); 61
60 sessions::SyncSourceInfo source_one( 62 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
61 sync_pb::GetUpdatesCallerInfo::NOTIFICATION, all_types); 63 nudge_tracker.updates_source());
62 sessions::SyncSourceInfo source_two( 64 EXPECT_TRUE(nudge_tracker.GetLocallyModifiedTypes().Empty());
63 sync_pb::GetUpdatesCallerInfo::LOCAL, one_type); 65
64 66 sync_pb::GetUpdateTriggers gu_trigger;
65 NudgeTracker tracker; 67 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
66 EXPECT_TRUE(tracker.IsEmpty()); 68
67 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Empty()); 69 SyncSourceInfo source_info = nudge_tracker.source_info();
68 70 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
69 tracker.CoalesceSources(source_one); 71 source_info.updates_source);
70 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Empty()); 72 }
71 73
72 tracker.CoalesceSources(source_two); 74 // Verify that nudges override each other based on a priority order.
73 // TODO: This result is wrong, but that's how the code has always been. A 75 // LOCAL < DATATYPE_REFRESH < NOTIFICATION
74 // local invalidation for a single type should mean that we have only one 76 TEST_F(NudgeTrackerTest, SourcePriorities) {
75 // locally modified source. It should not "inherit" the list of data types 77 NudgeTracker nudge_tracker;
76 // from the previous source. 78
77 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Equals( 79 // Track a local nudge.
78 ParamsMeaningAllEnabledTypes())); 80 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
79 } 81 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL,
80 82 nudge_tracker.updates_source());
81 TEST(NudgeTrackerTest, LocallyModifiedTypes_WithInvalidationSecond) { 83
82 ModelTypeInvalidationMap one_type = 84 // A refresh request will override it.
83 ModelTypeSetToInvalidationMap( 85 nudge_tracker.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS));
84 ParamsMeaningJustOneEnabledType(), 86 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH,
85 std::string()); 87 nudge_tracker.updates_source());
86 ModelTypeInvalidationMap all_types = 88
87 ModelTypeSetToInvalidationMap( 89 // Another local nudge will not be enough to change it.
88 ParamsMeaningAllEnabledTypes(), 90 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
89 std::string()); 91 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH,
90 sessions::SyncSourceInfo source_one( 92 nudge_tracker.updates_source());
91 sync_pb::GetUpdatesCallerInfo::LOCAL, one_type); 93
92 sessions::SyncSourceInfo source_two( 94 // An invalidation will override the refresh request source.
93 sync_pb::GetUpdatesCallerInfo::NOTIFICATION, all_types); 95 ModelTypeInvalidationMap invalidation_map =
94 96 ModelTypeSetToInvalidationMap(ModelTypeSet(PREFERENCES),
95 NudgeTracker tracker; 97 std::string("hint"));
96 EXPECT_TRUE(tracker.IsEmpty()); 98 nudge_tracker.RecordRemoteInvalidation(invalidation_map);
97 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Empty()); 99 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
98 100 nudge_tracker.updates_source());
99 tracker.CoalesceSources(source_one); 101
100 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Equals( 102 // Neither local nudges nor refresh requests will override it.
101 ParamsMeaningJustOneEnabledType())); 103 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
102 104 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
103 tracker.CoalesceSources(source_two); 105 nudge_tracker.updates_source());
104 106 nudge_tracker.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS));
105 // TODO: This result is wrong, but that's how the code has always been. 107 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
106 // The receipt of an invalidation should have no effect on the set of 108 nudge_tracker.updates_source());
107 // locally modified types. 109 }
108 EXPECT_TRUE(tracker.GetLocallyModifiedTypes().Empty()); 110
111 // Verify locally modified type coalescing and independence from other nudges.
112 TEST_F(NudgeTrackerTest, LocallyModifiedTypes) {
113 NudgeTracker nudge_tracker;
114
115 // Start with a notification. Verify it has no effect.
116 ModelTypeInvalidationMap invalidation_map1 =
117 ModelTypeSetToInvalidationMap(ModelTypeSet(PREFERENCES),
118 std::string("hint"));
119 nudge_tracker.RecordRemoteInvalidation(invalidation_map1);
120 EXPECT_TRUE(nudge_tracker.GetLocallyModifiedTypes().Empty());
121
122 // Record a local bookmark change. Verify it was registered correctly.
123 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
124 EXPECT_TRUE(ModelTypeSetEquals(
125 ModelTypeSet(BOOKMARKS),
126 nudge_tracker.GetLocallyModifiedTypes()));
127
128 // Record a notification and a refresh request. Verify they have no effect.
129 ModelTypeInvalidationMap invalidation_map2 =
130 ModelTypeSetToInvalidationMap(ModelTypeSet(PASSWORDS),
131 std::string("hint"));
132 nudge_tracker.RecordRemoteInvalidation(invalidation_map2);
133 EXPECT_TRUE(ModelTypeSetEquals(
134 ModelTypeSet(BOOKMARKS),
135 nudge_tracker.GetLocallyModifiedTypes()));
136
137 nudge_tracker.RecordLocalRefreshRequest(ModelTypeSet(AUTOFILL));
138 EXPECT_TRUE(ModelTypeSetEquals(
139 ModelTypeSet(BOOKMARKS),
140 nudge_tracker.GetLocallyModifiedTypes()));
141
142 // Record another local nudge. Verify it was coalesced correctly.
143 nudge_tracker.RecordLocalChange(ModelTypeSet(THEMES));
144 EXPECT_TRUE(ModelTypeSetEquals(
145 ModelTypeSet(THEMES, BOOKMARKS),
146 nudge_tracker.GetLocallyModifiedTypes()));
147 }
148
149 TEST_F(NudgeTrackerTest, HintCoalescing) {
150 NudgeTracker nudge_tracker;
151
152 // Easy case: record one hint.
153 {
154 ModelTypeInvalidationMap invalidation_map =
155 ModelTypeSetToInvalidationMap(ModelTypeSet(BOOKMARKS),
156 std::string("bm_hint_1"));
157 nudge_tracker.RecordRemoteInvalidation(invalidation_map);
158
159 sync_pb::GetUpdateTriggers gu_trigger;
160 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
161 ASSERT_EQ(1, gu_trigger.notification_hint_size());
162 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0));
163 EXPECT_FALSE(gu_trigger.client_dropped_hints());
164 }
165
166 // Record a second hint for the same type.
167 {
168 ModelTypeInvalidationMap invalidation_map =
169 ModelTypeSetToInvalidationMap(ModelTypeSet(BOOKMARKS),
170 std::string("bm_hint_2"));
171 nudge_tracker.RecordRemoteInvalidation(invalidation_map);
172
173 sync_pb::GetUpdateTriggers gu_trigger;
174 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
175 ASSERT_EQ(2, gu_trigger.notification_hint_size());
176
177 // Expect the most hint recent is last in the list.
178 EXPECT_EQ("bm_hint_1", gu_trigger.notification_hint(0));
179 EXPECT_EQ("bm_hint_2", gu_trigger.notification_hint(1));
180 EXPECT_FALSE(gu_trigger.client_dropped_hints());
181 }
182
183 // Record a hint for a different type.
184 {
185 ModelTypeInvalidationMap invalidation_map =
186 ModelTypeSetToInvalidationMap(ModelTypeSet(PASSWORDS),
187 std::string("pw_hint_1"));
188 nudge_tracker.RecordRemoteInvalidation(invalidation_map);
189
190 // Re-verify the bookmarks to make sure they're unaffected.
191 sync_pb::GetUpdateTriggers bm_gu_trigger;
192 nudge_tracker.FillProtoMessage(BOOKMARKS, &bm_gu_trigger);
193 ASSERT_EQ(2, bm_gu_trigger.notification_hint_size());
194 EXPECT_EQ("bm_hint_1", bm_gu_trigger.notification_hint(0));
195 EXPECT_EQ("bm_hint_2",
196 bm_gu_trigger.notification_hint(1)); // most recent last.
197 EXPECT_FALSE(bm_gu_trigger.client_dropped_hints());
198
199 // Verify the new type, too.
200 sync_pb::GetUpdateTriggers pw_gu_trigger;
201 nudge_tracker.FillProtoMessage(PASSWORDS, &pw_gu_trigger);
202 ASSERT_EQ(1, pw_gu_trigger.notification_hint_size());
203 EXPECT_EQ("pw_hint_1", pw_gu_trigger.notification_hint(0));
204 EXPECT_FALSE(pw_gu_trigger.client_dropped_hints());
205 }
206 }
207
208 TEST_F(NudgeTrackerTest, DropHintsLocally) {
209 NudgeTracker nudge_tracker;
210 ModelTypeInvalidationMap invalidation_map =
211 ModelTypeSetToInvalidationMap(ModelTypeSet(BOOKMARKS),
212 std::string("hint"));
213
214 for (size_t i = 0; i < GetHintBufferSize(); ++i) {
215 nudge_tracker.RecordRemoteInvalidation(invalidation_map);
216 }
217 {
218 sync_pb::GetUpdateTriggers gu_trigger;
219 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
220 EXPECT_EQ(GetHintBufferSize(),
221 static_cast<size_t>(gu_trigger.notification_hint_size()));
222 EXPECT_FALSE(gu_trigger.client_dropped_hints());
223 }
224
225 // Force an overflow.
226 ModelTypeInvalidationMap invalidation_map2 =
227 ModelTypeSetToInvalidationMap(ModelTypeSet(BOOKMARKS),
228 std::string("new_hint"));
229 nudge_tracker.RecordRemoteInvalidation(invalidation_map2);
230
231 {
232 sync_pb::GetUpdateTriggers gu_trigger;
233 nudge_tracker.FillProtoMessage(BOOKMARKS, &gu_trigger);
234 EXPECT_EQ(GetHintBufferSize(),
235 static_cast<size_t>(gu_trigger.notification_hint_size()));
236 EXPECT_TRUE(gu_trigger.client_dropped_hints());
237
238 // Verify the newest hint was not dropped and is the last in the list.
239 EXPECT_EQ("new_hint", gu_trigger.notification_hint(GetHintBufferSize()-1));
240
241 // Verify the oldest hint, too.
242 EXPECT_EQ("hint", gu_trigger.notification_hint(0));
243 }
244 }
245
246 // TODO(rlarocque): Add trickles support. See crbug.com/223437.
247 // TEST_F(NudgeTrackerTest, DropHintsAtServer);
248
249 // Checks the behaviour of the invalidations-out-of-sync flag.
250 TEST_F(NudgeTrackerTest, EnableDisableInvalidations) {
251 NudgeTracker nudge_tracker;
252
253 // By default, assume we're out of sync with the invalidation server.
254 EXPECT_TRUE(InvalidationsOutOfSync(nudge_tracker));
255
256 // Simply enabling invalidations does not bring us back into sync.
257 nudge_tracker.InvalidationsEnabled();
258 EXPECT_TRUE(InvalidationsOutOfSync(nudge_tracker));
259
260 // We must successfully complete a sync cycle while invalidations are enabled
261 // to be sure that we're in sync.
262 nudge_tracker.RecordSuccessfulSyncCycle();
263 EXPECT_FALSE(InvalidationsOutOfSync(nudge_tracker));
264
265 // If the invalidator malfunctions, we go become unsynced again.
266 nudge_tracker.InvalidationsDisabled();
267 EXPECT_TRUE(InvalidationsOutOfSync(nudge_tracker));
268
269 // A sync cycle while invalidations are disabled won't reset the flag.
270 nudge_tracker.RecordSuccessfulSyncCycle();
271 EXPECT_TRUE(InvalidationsOutOfSync(nudge_tracker));
272
273 // Nor will the re-enabling of invalidations be sufficient, even now that
274 // we've had a successful sync cycle.
275 nudge_tracker.RecordSuccessfulSyncCycle();
276 EXPECT_TRUE(InvalidationsOutOfSync(nudge_tracker));
277 }
278
279 // Tests that locally modified types are correctly written out to the
280 // GetUpdateTriggers proto.
281 TEST_F(NudgeTrackerTest, WriteLocallyModifiedTypesToProto) {
282 NudgeTracker nudge_tracker;
283
284 // Should not be locally modified by default.
285 EXPECT_EQ(0, ProtoLocallyModifiedCount(nudge_tracker, PREFERENCES));
286
287 // Record a local bookmark change. Verify it was registered correctly.
288 nudge_tracker.RecordLocalChange(ModelTypeSet(PREFERENCES));
289 EXPECT_EQ(1, ProtoLocallyModifiedCount(nudge_tracker, PREFERENCES));
290
291 // Record a successful sync cycle. Verify the count is cleared.
292 nudge_tracker.RecordSuccessfulSyncCycle();
293 EXPECT_EQ(0, ProtoLocallyModifiedCount(nudge_tracker, PREFERENCES));
294 }
295
296 // Tests that refresh requested types are correctly written out to the
297 // GetUpdateTriggers proto.
298 TEST_F(NudgeTrackerTest, WriteRefreshRequestedTypesToProto) {
299 NudgeTracker nudge_tracker;
300
301 // There should be no refresh requested by default.
302 EXPECT_EQ(0, ProtoRefreshRequestedCount(nudge_tracker, SESSIONS));
303
304 // Record a local refresh request. Verify it was registered correctly.
305 nudge_tracker.RecordLocalRefreshRequest(ModelTypeSet(SESSIONS));
306 EXPECT_EQ(1, ProtoRefreshRequestedCount(nudge_tracker, SESSIONS));
307
308 // Record a successful sync cycle. Verify the count is cleared.
309 nudge_tracker.RecordSuccessfulSyncCycle();
310 EXPECT_EQ(0, ProtoRefreshRequestedCount(nudge_tracker, SESSIONS));
109 } 311 }
110 312
111 } // namespace sessions 313 } // namespace sessions
112 } // namespace syncer 314 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698