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

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

Powered by Google App Engine
This is Rietveld 408576698