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

Side by Side Diff: chrome/browser/sync/engine/syncer_thread2_unittest.cc

Issue 6812004: sync: Make nudge + config jobs reliable in SyncerThread2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: upload before commit. Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/synchronization/waitable_event.h" 5 #include "base/synchronization/waitable_event.h"
6 #include "base/test/test_timeouts.h" 6 #include "base/test/test_timeouts.h"
7 #include "chrome/browser/sync/engine/mock_model_safe_workers.h" 7 #include "chrome/browser/sync/engine/mock_model_safe_workers.h"
8 #include "chrome/browser/sync/engine/syncer.h" 8 #include "chrome/browser/sync/engine/syncer.h"
9 #include "chrome/browser/sync/engine/syncer_thread2.h" 9 #include "chrome/browser/sync/engine/syncer_thread2.h"
10 #include "chrome/browser/sync/sessions/test_util.h" 10 #include "chrome/browser/sync/sessions/test_util.h"
(...skipping 29 matching lines...) Expand all
40 namespace s3 { 40 namespace s3 {
41 41
42 // Used when tests want to record syncing activity to examine later. 42 // Used when tests want to record syncing activity to examine later.
43 struct SyncShareRecords { 43 struct SyncShareRecords {
44 std::vector<TimeTicks> times; 44 std::vector<TimeTicks> times;
45 std::vector<linked_ptr<SyncSessionSnapshot> > snapshots; 45 std::vector<linked_ptr<SyncSessionSnapshot> > snapshots;
46 }; 46 };
47 47
48 // Convenient to use in tests wishing to analyze SyncShare calls over time. 48 // Convenient to use in tests wishing to analyze SyncShare calls over time.
49 static const size_t kMinNumSamples = 5; 49 static const size_t kMinNumSamples = 5;
50
51 class SyncerThread2Test : public testing::Test { 50 class SyncerThread2Test : public testing::Test {
52 public: 51 public:
53 class MockDelayProvider : public SyncerThread::DelayProvider { 52 class MockDelayProvider : public SyncerThread::DelayProvider {
54 public: 53 public:
55 MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&)); 54 MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&));
56 }; 55 };
57 56
58 virtual void SetUp() { 57 virtual void SetUp() {
59 syncdb_.SetUp(); 58 syncdb_.SetUp();
60 syncer_ = new MockSyncer(); 59 syncer_ = new MockSyncer();
61 delay_ = NULL; 60 delay_ = NULL;
62 registrar_.reset(MockModelSafeWorkerRegistrar::PassiveBookmarks()); 61 registrar_.reset(MockModelSafeWorkerRegistrar::PassiveBookmarks());
63 connection_.reset(new MockConnectionManager(syncdb_.manager(), "Test")); 62 connection_.reset(new MockConnectionManager(syncdb_.manager(), "Test"));
64 connection_->SetServerReachable(); 63 connection_->SetServerReachable();
65 context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(), 64 context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(),
66 registrar_.get(), std::vector<SyncEngineEventListener*>()); 65 registrar_.get(), std::vector<SyncEngineEventListener*>());
67 context_->set_notifications_enabled(true); 66 context_->set_notifications_enabled(true);
68 context_->set_account_name("Test"); 67 context_->set_account_name("Test");
69 syncer_thread_.reset(new SyncerThread(context_, syncer_)); 68 syncer_thread_.reset(new SyncerThread(context_, syncer_));
70 } 69 }
71 70
71 virtual void SetUpWithTypes(syncable::ModelTypeBitSet types) {
72 syncdb_.SetUp();
73 syncer_ = new MockSyncer();
74 delay_ = NULL;
75 registrar_.reset(MockModelSafeWorkerRegistrar::PassiveForTypes(types));
76 connection_.reset(new MockConnectionManager(syncdb_.manager(), "Test"));
77 connection_->SetServerReachable();
78 context_ = new SyncSessionContext(connection_.get(), syncdb_.manager(),
79 registrar_.get(), std::vector<SyncEngineEventListener*>());
80 context_->set_notifications_enabled(true);
81 context_->set_account_name("Test");
82 syncer_thread_.reset(new SyncerThread(context_, syncer_));
83 }
84
72 SyncerThread* syncer_thread() { return syncer_thread_.get(); } 85 SyncerThread* syncer_thread() { return syncer_thread_.get(); }
73 MockSyncer* syncer() { return syncer_; } 86 MockSyncer* syncer() { return syncer_; }
74 MockDelayProvider* delay() { return delay_; } 87 MockDelayProvider* delay() { return delay_; }
75 MockConnectionManager* connection() { return connection_.get(); } 88 MockConnectionManager* connection() { return connection_.get(); }
76 TimeDelta zero() { return TimeDelta::FromSeconds(0); } 89 TimeDelta zero() { return TimeDelta::FromSeconds(0); }
77 TimeDelta timeout() { 90 TimeDelta timeout() {
78 return TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()); 91 return TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms());
79 } 92 }
80 93
81 virtual void TearDown() { 94 virtual void TearDown() {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 FROM_HERE); 233 FROM_HERE);
221 done.TimedWait(timeout()); 234 done.TimedWait(timeout());
222 235
223 EXPECT_EQ(1U, records2.snapshots.size()); 236 EXPECT_EQ(1U, records2.snapshots.size());
224 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types, 237 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
225 records2.snapshots[0]->source.types)); 238 records2.snapshots[0]->source.types));
226 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, 239 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
227 records2.snapshots[0]->source.updates_source); 240 records2.snapshots[0]->source.updates_source);
228 } 241 }
229 242
243 // Make sure a regular config command is scheduled fine in the absence of any
244 // errors.
245 TEST_F(SyncerThread2Test, Config) {
246 base::WaitableEvent done(false, false);
247 SyncShareRecords records;
248 syncable::ModelTypeBitSet model_types;
249 model_types[syncable::BOOKMARKS] = true;
250
251 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
252 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
253 WithArg<0>(RecordSyncShare(&records, 1U, &done))));
254
255 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
256
257 syncer_thread()->ScheduleConfig(model_types);
258 done.TimedWait(timeout());
259
260 EXPECT_EQ(1U, records.snapshots.size());
261 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
262 records.snapshots[0]->source.types));
263 EXPECT_EQ(GetUpdatesCallerInfo::FIRST_UPDATE,
264 records.snapshots[0]->source.updates_source);
265 }
266
267 // Simulate a failure and make sure the config request is retried.
268 TEST_F(SyncerThread2Test, ConfigWithBackingOff) {
269 base::WaitableEvent done(false, false);
270 base::WaitableEvent* dummy = NULL;
271 UseMockDelayProvider();
272 EXPECT_CALL(*delay(), GetDelay(_))
273 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1)));
274 SyncShareRecords records;
275 syncable::ModelTypeBitSet model_types;
276 model_types[syncable::BOOKMARKS] = true;
277
278 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
279 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
280 WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
281 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
282 WithArg<0>(RecordSyncShare(&records, 1U, &done))));
283
284 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
285
286 syncer_thread()->ScheduleConfig(model_types);
287 done.TimedWait(timeout());
288
289 EXPECT_EQ(2U, records.snapshots.size());
290 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
291 records.snapshots[1]->source.types));
292 EXPECT_EQ(GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION,
293 records.snapshots[1]->source.updates_source);
294 }
295
296 // Issue 2 config commands. Second one right after the first has failed
297 // and make sure LATEST is executed.
298 TEST_F(SyncerThread2Test, MultipleConfigWithBackingOff) {
299 syncable::ModelTypeBitSet model_types1, model_types2;
300 model_types1[syncable::BOOKMARKS] = true;
301 model_types2[syncable::AUTOFILL] = true;
302 SetUpWithTypes(model_types1 | model_types2);
303 base::WaitableEvent done(false, false);
304 base::WaitableEvent done1(false, false);
305 base::WaitableEvent* dummy = NULL;
306 UseMockDelayProvider();
307 EXPECT_CALL(*delay(), GetDelay(_))
308 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(30)));
309 SyncShareRecords records;
310
311 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
312 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
313 WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
314 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
315 WithArg<0>(RecordSyncShare(&records, 1U, &done1))))
316 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
317 WithArg<0>(RecordSyncShare(&records, 1U, &done))));
318
319 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
320
321 syncer_thread()->ScheduleConfig(model_types1);
322
323 // done1 indicates the first config failed.
324 done1.TimedWait(timeout());
325 syncer_thread()->ScheduleConfig(model_types2);
326 done.TimedWait(timeout());
327
328 EXPECT_EQ(3U, records.snapshots.size());
329 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types2,
330 records.snapshots[2]->source.types));
331 EXPECT_EQ(GetUpdatesCallerInfo::FIRST_UPDATE,
332 records.snapshots[2]->source.updates_source);
333 }
334
335 // Issue a nudge when the config has failed. Make sure both the config and
336 // nudge are executed.
337 TEST_F(SyncerThread2Test, NudgeWithConfigWithBackingOff) {
338 syncable::ModelTypeBitSet model_types;
339 model_types[syncable::BOOKMARKS] = true;
340 base::WaitableEvent done(false, false);
341 base::WaitableEvent done1(false, false);
342 base::WaitableEvent done2(false, false);
343 base::WaitableEvent* dummy = NULL;
344 UseMockDelayProvider();
345 EXPECT_CALL(*delay(), GetDelay(_))
346 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50)));
347 SyncShareRecords records;
348
349 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
350 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
351 WithArg<0>(RecordSyncShare(&records, 1U, dummy))))
352 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed),
353 WithArg<0>(RecordSyncShare(&records, 1U, &done1))))
354 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
355 WithArg<0>(RecordSyncShare(&records, 1U, &done2))))
356 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
357 WithArg<0>(RecordSyncShare(&records, 1U, &done))));
358
359 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
360
361 syncer_thread()->ScheduleConfig(model_types);
362 done1.TimedWait(timeout());
363 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, model_types,
364 FROM_HERE);
365
366 // done2 indicates config suceeded. Now change the mode so nudge can execute.
367 done2.TimedWait(timeout());
368 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
369 done.TimedWait(timeout());
370 EXPECT_EQ(4U, records.snapshots.size());
371
372 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
373 records.snapshots[2]->source.types));
374 EXPECT_EQ(GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION,
375 records.snapshots[2]->source.updates_source);
376
377 EXPECT_TRUE(CompareModelTypeBitSetToModelTypePayloadMap(model_types,
378 records.snapshots[3]->source.types));
379 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL,
380 records.snapshots[3]->source.updates_source);
381
382 }
383
384
230 // Test that nudges are coalesced. 385 // Test that nudges are coalesced.
231 TEST_F(SyncerThread2Test, NudgeCoalescing) { 386 TEST_F(SyncerThread2Test, NudgeCoalescing) {
232 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL); 387 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
233 base::WaitableEvent done(false, false); 388 base::WaitableEvent done(false, false);
234 SyncShareRecords r; 389 SyncShareRecords r;
235 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) 390 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
236 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), 391 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
237 WithArg<0>(RecordSyncShare(&r, 1U, &done)))); 392 WithArg<0>(RecordSyncShare(&r, 1U, &done))));
238 syncable::ModelTypeBitSet types1, types2, types3; 393 syncable::ModelTypeBitSet types1, types2, types3;
239 types1[syncable::BOOKMARKS] = true; 394 types1[syncable::BOOKMARKS] = true;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 624 }
470 625
471 // Test nudges / polls don't run in config mode and config tasks do. 626 // Test nudges / polls don't run in config mode and config tasks do.
472 TEST_F(SyncerThread2Test, ConfigurationMode) { 627 TEST_F(SyncerThread2Test, ConfigurationMode) {
473 TimeDelta poll(TimeDelta::FromMilliseconds(15)); 628 TimeDelta poll(TimeDelta::FromMilliseconds(15));
474 SyncShareRecords records; 629 SyncShareRecords records;
475 base::WaitableEvent done(false, false); 630 base::WaitableEvent done(false, false);
476 base::WaitableEvent* dummy = NULL; 631 base::WaitableEvent* dummy = NULL;
477 syncer_thread()->OnReceivedLongPollIntervalUpdate(poll); 632 syncer_thread()->OnReceivedLongPollIntervalUpdate(poll);
478 EXPECT_CALL(*syncer(), SyncShare(_,_,_)) 633 EXPECT_CALL(*syncer(), SyncShare(_,_,_))
479 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess), 634 .WillOnce((Invoke(sessions::test_util::SimulateSuccess),
480 WithArg<0>(RecordSyncShare(&records, 1U, dummy)))); 635 WithArg<0>(RecordSyncShare(&records, 1U, dummy))));
481 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL); 636 syncer_thread()->Start(SyncerThread::CONFIGURATION_MODE, NULL);
482 syncable::ModelTypeBitSet nudge_types; 637 syncable::ModelTypeBitSet nudge_types;
483 nudge_types[syncable::AUTOFILL] = true; 638 nudge_types[syncable::AUTOFILL] = true;
484 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types, 639 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types,
485 FROM_HERE); 640 FROM_HERE);
486 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types, 641 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, nudge_types,
487 FROM_HERE); 642 FROM_HERE);
488 643
489 syncable::ModelTypeBitSet config_types; 644 syncable::ModelTypeBitSet config_types;
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 // TODO(tim): Implement this test and then the functionality! 887 // TODO(tim): Implement this test and then the functionality!
733 TEST_F(SyncerThread2Test, DISABLED_NoConfigDuringNormal) { 888 TEST_F(SyncerThread2Test, DISABLED_NoConfigDuringNormal) {
734 } 889 }
735 890
736 // Test that starting the syncer thread without a valid connection doesn't 891 // Test that starting the syncer thread without a valid connection doesn't
737 // break things when a connection is detected. 892 // break things when a connection is detected.
738 TEST_F(SyncerThread2Test, StartWhenNotConnected) { 893 TEST_F(SyncerThread2Test, StartWhenNotConnected) {
739 base::WaitableEvent done(false, false); 894 base::WaitableEvent done(false, false);
740 MessageLoop cur; 895 MessageLoop cur;
741 connection()->SetServerNotReachable(); 896 connection()->SetServerNotReachable();
897 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).WillOnce(SignalEvent(&done));
742 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL); 898 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
743 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(), 899 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
744 FROM_HERE); 900 FROM_HERE);
745 FlushLastTask(&done); 901 FlushLastTask(&done);
746 902
747 connection()->SetServerReachable(); 903 connection()->SetServerReachable();
748 cur.PostTask(FROM_HERE, NewRunnableFunction( 904 cur.PostTask(FROM_HERE, NewRunnableFunction(
749 &SyncerThread2Test::QuitMessageLoop)); 905 &SyncerThread2Test::QuitMessageLoop));
750 cur.Run(); 906 cur.Run();
751 907
752 // By now, the server connection event should have been posted to the 908 // By now, the server connection event should have been posted to the
753 // SyncerThread. 909 // SyncerThread.
754 FlushLastTask(&done); 910 FlushLastTask(&done);
755 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).WillOnce(SignalEvent(&done));
756 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
757 FROM_HERE);
758 done.TimedWait(timeout()); 911 done.TimedWait(timeout());
759 } 912 }
760 913
761 TEST_F(SyncerThread2Test, SetsPreviousRoutingInfo) { 914 TEST_F(SyncerThread2Test, SetsPreviousRoutingInfo) {
762 base::WaitableEvent done(false, false); 915 base::WaitableEvent done(false, false);
763 ModelSafeRoutingInfo info; 916 ModelSafeRoutingInfo info;
764 EXPECT_TRUE(info == context()->previous_session_routing_info()); 917 EXPECT_TRUE(info == context()->previous_session_routing_info());
765 ModelSafeRoutingInfo expected; 918 ModelSafeRoutingInfo expected;
766 context()->registrar()->GetModelSafeRoutingInfo(&expected); 919 context()->registrar()->GetModelSafeRoutingInfo(&expected);
767 ASSERT_FALSE(expected.empty()); 920 ASSERT_FALSE(expected.empty());
768 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1); 921 EXPECT_CALL(*syncer(), SyncShare(_,_,_)).Times(1);
769 922
770 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL); 923 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
771 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(), 924 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet(),
772 FROM_HERE); 925 FROM_HERE);
773 FlushLastTask(&done); 926 FlushLastTask(&done);
774 syncer_thread()->Stop(); 927 syncer_thread()->Stop();
775 928
776 EXPECT_TRUE(expected == context()->previous_session_routing_info()); 929 EXPECT_TRUE(expected == context()->previous_session_routing_info());
777 } 930 }
778 931
779 } // namespace s3 932 } // namespace s3
780 } // namespace browser_sync 933 } // namespace browser_sync
781 934
782 // SyncerThread won't outlive the test! 935 // SyncerThread won't outlive the test!
783 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::s3::SyncerThread2Test); 936 DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::s3::SyncerThread2Test);
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_thread2.cc ('k') | chrome/browser/sync/engine/syncer_thread2_whitebox_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698