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/bind.h" | 5 #include "base/bind.h" |
6 #include "base/callback.h" | 6 #include "base/callback.h" |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 struct SyncShareRecords { | 50 struct SyncShareRecords { |
51 std::vector<TimeTicks> times; | 51 std::vector<TimeTicks> times; |
52 std::vector<SyncSessionSnapshot> snapshots; | 52 std::vector<SyncSessionSnapshot> snapshots; |
53 }; | 53 }; |
54 | 54 |
55 void QuitLoopNow() { | 55 void QuitLoopNow() { |
56 // We use QuitNow() instead of Quit() as the latter may get stalled | 56 // We use QuitNow() instead of Quit() as the latter may get stalled |
57 // indefinitely in the presence of repeated timers with low delays | 57 // indefinitely in the presence of repeated timers with low delays |
58 // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll | 58 // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll |
59 // delay of 5ms] run under TSAN on the trybots). | 59 // delay of 5ms] run under TSAN on the trybots). |
60 MessageLoop::current()->QuitNow(); | 60 base::MessageLoop::current()->QuitNow(); |
61 } | 61 } |
62 | 62 |
63 void RunLoop() { | 63 void RunLoop() { |
64 MessageLoop::current()->Run(); | 64 base::MessageLoop::current()->Run(); |
65 } | 65 } |
66 | 66 |
67 void PumpLoop() { | 67 void PumpLoop() { |
68 // Do it this way instead of RunAllPending to pump loop exactly once | 68 // Do it this way instead of RunAllPending to pump loop exactly once |
69 // (necessary in the presence of timers; see comment in | 69 // (necessary in the presence of timers; see comment in |
70 // QuitLoopNow). | 70 // QuitLoopNow). |
71 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&QuitLoopNow)); | 71 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&QuitLoopNow)); |
72 RunLoop(); | 72 RunLoop(); |
73 } | 73 } |
74 | 74 |
75 void PumpLoopFor(base::TimeDelta time) { | 75 void PumpLoopFor(base::TimeDelta time) { |
76 // Allow the loop to run for the specified amount of time. | 76 // Allow the loop to run for the specified amount of time. |
77 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 77 base::MessageLoop::current()->PostDelayedTask( |
78 base::Bind(&QuitLoopNow), | 78 FROM_HERE, base::Bind(&QuitLoopNow), time); |
79 time); | |
80 RunLoop(); | 79 RunLoop(); |
81 } | 80 } |
82 | 81 |
83 ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) { | 82 ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) { |
84 ModelSafeRoutingInfo routes; | 83 ModelSafeRoutingInfo routes; |
85 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 84 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
86 routes[iter.Get()] = GROUP_PASSIVE; | 85 routes[iter.Get()] = GROUP_PASSIVE; |
87 } | 86 } |
88 return routes; | 87 return routes; |
89 } | 88 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 } | 225 } |
227 | 226 |
228 SyncSessionContext* context() { return context_.get(); } | 227 SyncSessionContext* context() { return context_.get(); } |
229 | 228 |
230 private: | 229 private: |
231 syncable::Directory* directory() { | 230 syncable::Directory* directory() { |
232 return dir_maker_.directory(); | 231 return dir_maker_.directory(); |
233 } | 232 } |
234 | 233 |
235 base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_; | 234 base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_; |
236 MessageLoop message_loop_; | 235 base::MessageLoop message_loop_; |
237 TestDirectorySetterUpper dir_maker_; | 236 TestDirectorySetterUpper dir_maker_; |
238 scoped_ptr<MockConnectionManager> connection_; | 237 scoped_ptr<MockConnectionManager> connection_; |
239 scoped_ptr<SyncSessionContext> context_; | 238 scoped_ptr<SyncSessionContext> context_; |
240 scoped_ptr<SyncSchedulerImpl> scheduler_; | 239 scoped_ptr<SyncSchedulerImpl> scheduler_; |
241 MockSyncer* syncer_; | 240 MockSyncer* syncer_; |
242 MockDelayProvider* delay_; | 241 MockDelayProvider* delay_; |
243 std::vector<scoped_refptr<FakeModelWorker> > workers_; | 242 std::vector<scoped_refptr<FakeModelWorker> > workers_; |
244 FakeExtensionsActivityMonitor extensions_activity_monitor_; | 243 FakeExtensionsActivityMonitor extensions_activity_monitor_; |
245 scoped_ptr<ThrottledDataTypeTracker> throttled_data_type_tracker_; | 244 scoped_ptr<ThrottledDataTypeTracker> throttled_data_type_tracker_; |
246 ModelSafeRoutingInfo routing_info_; | 245 ModelSafeRoutingInfo routing_info_; |
247 }; | 246 }; |
248 | 247 |
249 void RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record) { | 248 void RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record) { |
250 record->times.push_back(TimeTicks::Now()); | 249 record->times.push_back(TimeTicks::Now()); |
251 record->snapshots.push_back(s->TakeSnapshot()); | 250 record->snapshots.push_back(s->TakeSnapshot()); |
252 } | 251 } |
253 | 252 |
254 ACTION_P(RecordSyncShare, record) { | 253 ACTION_P(RecordSyncShare, record) { |
255 RecordSyncShareImpl(arg0, record); | 254 RecordSyncShareImpl(arg0, record); |
256 if (MessageLoop::current()->is_running()) | 255 if (base::MessageLoop::current()->is_running()) |
257 QuitLoopNow(); | 256 QuitLoopNow(); |
258 return true; | 257 return true; |
259 } | 258 } |
260 | 259 |
261 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { | 260 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { |
262 RecordSyncShareImpl(arg0, record); | 261 RecordSyncShareImpl(arg0, record); |
263 EXPECT_LE(record->times.size(), quit_after); | 262 EXPECT_LE(record->times.size(), quit_after); |
264 if (record->times.size() >= quit_after && | 263 if (record->times.size() >= quit_after && |
265 MessageLoop::current()->is_running()) { | 264 base::MessageLoop::current()->is_running()) { |
266 QuitLoopNow(); | 265 QuitLoopNow(); |
267 } | 266 } |
268 return true; | 267 return true; |
269 } | 268 } |
270 | 269 |
271 ACTION(AddFailureAndQuitLoopNow) { | 270 ACTION(AddFailureAndQuitLoopNow) { |
272 ADD_FAILURE(); | 271 ADD_FAILURE(); |
273 QuitLoopNow(); | 272 QuitLoopNow(); |
274 return true; | 273 return true; |
275 } | 274 } |
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 1189 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
1191 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), | 1190 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), |
1192 Return(true))) | 1191 Return(true))) |
1193 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 1192 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
1194 Return(true))); | 1193 Return(true))); |
1195 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1194 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
1196 | 1195 |
1197 scheduler()->ScheduleNudgeAsync( | 1196 scheduler()->ScheduleNudgeAsync( |
1198 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); | 1197 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); |
1199 // Should save the nudge for until after the server is reachable. | 1198 // Should save the nudge for until after the server is reachable. |
1200 MessageLoop::current()->RunUntilIdle(); | 1199 base::MessageLoop::current()->RunUntilIdle(); |
1201 | 1200 |
1202 scheduler()->OnConnectionStatusChange(); | 1201 scheduler()->OnConnectionStatusChange(); |
1203 connection()->SetServerReachable(); | 1202 connection()->SetServerReachable(); |
1204 connection()->UpdateConnectionStatus(); | 1203 connection()->UpdateConnectionStatus(); |
1205 MessageLoop::current()->RunUntilIdle(); | 1204 base::MessageLoop::current()->RunUntilIdle(); |
1206 } | 1205 } |
1207 | 1206 |
1208 TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) { | 1207 TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) { |
1209 UseMockDelayProvider(); | 1208 UseMockDelayProvider(); |
1210 EXPECT_CALL(*delay(), GetDelay(_)) | 1209 EXPECT_CALL(*delay(), GetDelay(_)) |
1211 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); | 1210 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); |
1212 | 1211 |
1213 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1212 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
1214 connection()->SetServerNotReachable(); | 1213 connection()->SetServerNotReachable(); |
1215 connection()->UpdateConnectionStatus(); | 1214 connection()->UpdateConnectionStatus(); |
1216 | 1215 |
1217 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) | 1216 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) |
1218 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), | 1217 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), |
1219 Return(true))) | 1218 Return(true))) |
1220 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), | 1219 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), |
1221 Return(true))); | 1220 Return(true))); |
1222 | 1221 |
1223 scheduler()->ScheduleNudgeAsync( | 1222 scheduler()->ScheduleNudgeAsync( |
1224 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); | 1223 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); |
1225 | 1224 |
1226 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1225 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
1227 ASSERT_TRUE(scheduler()->IsBackingOff()); | 1226 ASSERT_TRUE(scheduler()->IsBackingOff()); |
1228 | 1227 |
1229 // Before we run the scheduled canary, trigger a server connection change. | 1228 // Before we run the scheduled canary, trigger a server connection change. |
1230 scheduler()->OnConnectionStatusChange(); | 1229 scheduler()->OnConnectionStatusChange(); |
1231 connection()->SetServerReachable(); | 1230 connection()->SetServerReachable(); |
1232 connection()->UpdateConnectionStatus(); | 1231 connection()->UpdateConnectionStatus(); |
1233 MessageLoop::current()->RunUntilIdle(); | 1232 base::MessageLoop::current()->RunUntilIdle(); |
1234 } | 1233 } |
1235 | 1234 |
1236 // This was supposed to test the scenario where we receive a nudge while a | 1235 // This was supposed to test the scenario where we receive a nudge while a |
1237 // connection change canary is scheduled, but has not run yet. Since we've made | 1236 // connection change canary is scheduled, but has not run yet. Since we've made |
1238 // the connection change canary synchronous, this is no longer possible. | 1237 // the connection change canary synchronous, this is no longer possible. |
1239 TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) { | 1238 TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) { |
1240 UseMockDelayProvider(); | 1239 UseMockDelayProvider(); |
1241 EXPECT_CALL(*delay(), GetDelay(_)) | 1240 EXPECT_CALL(*delay(), GetDelay(_)) |
1242 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); | 1241 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); |
1243 | 1242 |
(...skipping 14 matching lines...) Expand all Loading... |
1258 | 1257 |
1259 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1258 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
1260 ASSERT_TRUE(scheduler()->IsBackingOff()); | 1259 ASSERT_TRUE(scheduler()->IsBackingOff()); |
1261 | 1260 |
1262 // Before we run the scheduled canary, trigger a server connection change. | 1261 // Before we run the scheduled canary, trigger a server connection change. |
1263 scheduler()->OnConnectionStatusChange(); | 1262 scheduler()->OnConnectionStatusChange(); |
1264 connection()->SetServerReachable(); | 1263 connection()->SetServerReachable(); |
1265 connection()->UpdateConnectionStatus(); | 1264 connection()->UpdateConnectionStatus(); |
1266 scheduler()->ScheduleNudgeAsync( | 1265 scheduler()->ScheduleNudgeAsync( |
1267 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); | 1266 zero(), NUDGE_SOURCE_LOCAL, ModelTypeSet(BOOKMARKS), FROM_HERE); |
1268 MessageLoop::current()->RunUntilIdle(); | 1267 base::MessageLoop::current()->RunUntilIdle(); |
1269 } | 1268 } |
1270 | 1269 |
1271 // Tests that we don't crash trying to run two canaries at once if we receive | 1270 // Tests that we don't crash trying to run two canaries at once if we receive |
1272 // extra connection status change notifications. See crbug.com/190085. | 1271 // extra connection status change notifications. See crbug.com/190085. |
1273 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { | 1272 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { |
1274 EXPECT_CALL(*syncer(), SyncShare(_, DOWNLOAD_UPDATES, APPLY_UPDATES)) | 1273 EXPECT_CALL(*syncer(), SyncShare(_, DOWNLOAD_UPDATES, APPLY_UPDATES)) |
1275 .WillRepeatedly(DoAll( | 1274 .WillRepeatedly(DoAll( |
1276 Invoke(sessions::test_util::SimulateConnectionFailure), | 1275 Invoke(sessions::test_util::SimulateConnectionFailure), |
1277 Return(true))); | 1276 Return(true))); |
1278 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 1277 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
1279 connection()->SetServerNotReachable(); | 1278 connection()->SetServerNotReachable(); |
1280 connection()->UpdateConnectionStatus(); | 1279 connection()->UpdateConnectionStatus(); |
1281 | 1280 |
1282 ModelTypeSet model_types(BOOKMARKS); | 1281 ModelTypeSet model_types(BOOKMARKS); |
1283 CallbackCounter counter; | 1282 CallbackCounter counter; |
1284 ConfigurationParams params( | 1283 ConfigurationParams params( |
1285 GetUpdatesCallerInfo::RECONFIGURATION, | 1284 GetUpdatesCallerInfo::RECONFIGURATION, |
1286 model_types, | 1285 model_types, |
1287 TypesToRoutingInfo(model_types), | 1286 TypesToRoutingInfo(model_types), |
1288 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 1287 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
1289 scheduler()->ScheduleConfiguration(params); | 1288 scheduler()->ScheduleConfiguration(params); |
1290 | 1289 |
1291 scheduler()->OnConnectionStatusChange(); | 1290 scheduler()->OnConnectionStatusChange(); |
1292 scheduler()->OnConnectionStatusChange(); | 1291 scheduler()->OnConnectionStatusChange(); |
1293 | 1292 |
1294 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1293 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
1295 } | 1294 } |
1296 | 1295 |
1297 } // namespace syncer | 1296 } // namespace syncer |
OLD | NEW |