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_thread_unittest.cc

Issue 6874018: make new syncer thread the default. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Upload before submit. 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
5 #include <list>
6 #include <map>
7
8 #include "base/memory/scoped_ptr.h"
9 #include "base/synchronization/lock.h"
10 #include "base/time.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "chrome/browser/sync/engine/model_safe_worker.h"
13 #include "chrome/browser/sync/engine/syncer_thread.h"
14 #include "chrome/browser/sync/engine/syncer_types.h"
15 #include "chrome/browser/sync/sessions/sync_session_context.h"
16 #include "chrome/browser/sync/util/channel.h"
17 #include "chrome/test/sync/engine/mock_connection_manager.h"
18 #include "chrome/test/sync/engine/test_directory_setter_upper.h"
19 #include "chrome/test/sync/sessions/test_scoped_session_event_listener.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using base::TimeTicks;
24 using base::TimeDelta;
25 using base::WaitableEvent;
26 using testing::_;
27 using testing::AnyNumber;
28 using testing::Field;
29
30 namespace browser_sync {
31 using sessions::ErrorCounters;
32 using sessions::TestScopedSessionEventListener;
33 using sessions::SyncSessionContext;
34 using sessions::SyncSessionSnapshot;
35 using sessions::SyncerStatus;
36
37 typedef testing::Test SyncerThreadTest;
38 typedef SyncerThread::WaitInterval WaitInterval;
39
40 ACTION_P(SignalEvent, event) {
41 event->Signal();
42 }
43
44 SyncSessionSnapshot SessionSnapshotForTest(
45 int64 num_server_changes_remaining,
46 int64 unsynced_count) {
47 std::string download_progress_markers[syncable::MODEL_TYPE_COUNT];
48 for (int i = syncable::FIRST_REAL_MODEL_TYPE;
49 i < syncable::MODEL_TYPE_COUNT;
50 ++i) {
51 syncable::ModelType type(syncable::ModelTypeFromInt(i));
52 sync_pb::DataTypeProgressMarker token;
53 token.set_data_type_id(
54 syncable::GetExtensionFieldNumberFromModelType(type));
55 token.set_token("foobar");
56 token.SerializeToString(&download_progress_markers[i]);
57 }
58 return SyncSessionSnapshot(SyncerStatus(), ErrorCounters(),
59 num_server_changes_remaining, false,
60 syncable::ModelTypeBitSet(), download_progress_markers,
61 false, false, unsynced_count, 0, false, sessions::SyncSourceInfo());
62 }
63
64 class ListenerMock : public SyncEngineEventListener {
65 public:
66 MOCK_METHOD1(OnSyncEngineEvent, void(const SyncEngineEvent&));
67 };
68
69 class SyncerThreadWithSyncerTest : public testing::Test,
70 public ModelSafeWorkerRegistrar,
71 public SyncEngineEventListener {
72 public:
73 SyncerThreadWithSyncerTest()
74 : max_wait_time_(TimeDelta::FromSeconds(10)),
75 sync_cycle_ended_event_(false, false) {}
76 virtual void SetUp() {
77 metadb_.SetUp();
78 connection_.reset(new MockConnectionManager(metadb_.manager(),
79 metadb_.name()));
80 worker_ = new ModelSafeWorker();
81 std::vector<SyncEngineEventListener*> listeners;
82 listeners.push_back(this);
83 context_ = new SyncSessionContext(connection_.get(), metadb_.manager(),
84 this, listeners);
85 context_->set_account_name(metadb_.name());
86 syncer_thread_ = new SyncerThread(context_);
87 syncer_thread_->SetConnected(true);
88 syncable::ModelTypeBitSet expected_types;
89 expected_types[syncable::BOOKMARKS] = true;
90 connection_->ExpectGetUpdatesRequestTypes(expected_types);
91 }
92 virtual void TearDown() {
93 context_ = NULL;
94 syncer_thread_ = NULL;
95 connection_.reset();
96 metadb_.TearDown();
97 }
98
99 // ModelSafeWorkerRegistrar implementation.
100 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) {
101 out->push_back(worker_.get());
102 }
103
104 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) {
105 // We're just testing the sync engine here, so we shunt everything to
106 // the SyncerThread.
107 (*out)[syncable::BOOKMARKS] = GROUP_PASSIVE;
108 }
109
110 ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; }
111 MockConnectionManager* connection() { return connection_.get(); }
112 SyncerThread* syncer_thread() { return syncer_thread_; }
113
114 // Waits an indefinite amount of sync cycles for the syncer thread to become
115 // throttled. Only call this if a throttle is supposed to occur!
116 bool WaitForThrottle() {
117 int max_cycles = 5;
118 while (max_cycles && !syncer_thread()->IsSyncingCurrentlySilenced()) {
119 sync_cycle_ended_event_.TimedWait(max_wait_time_);
120 max_cycles--;
121 }
122
123 return syncer_thread()->IsSyncingCurrentlySilenced();
124 }
125
126 void WaitForDisconnect() {
127 // Wait for the SyncerThread to detect loss of connection, up to a max of
128 // 10 seconds to timeout the test.
129 base::AutoLock lock(syncer_thread()->lock_);
130 TimeTicks start = TimeTicks::Now();
131 TimeDelta ten_seconds = TimeDelta::FromSeconds(10);
132 while (syncer_thread()->vault_.connected_) {
133 syncer_thread()->vault_field_changed_.TimedWait(ten_seconds);
134 if (TimeTicks::Now() - start > ten_seconds)
135 break;
136 }
137 EXPECT_FALSE(syncer_thread()->vault_.connected_);
138 }
139
140 bool Pause(ListenerMock* listener) {
141 WaitableEvent event(false, false);
142 {
143 base::AutoLock lock(syncer_thread()->lock_);
144 EXPECT_CALL(*listener, OnSyncEngineEvent(
145 Field(&SyncEngineEvent::what_happened,
146 SyncEngineEvent::SYNCER_THREAD_PAUSED))).
147 WillOnce(SignalEvent(&event));
148 }
149 if (!syncer_thread()->RequestPause())
150 return false;
151 return event.TimedWait(max_wait_time_);
152 }
153
154 bool Resume(ListenerMock* listener) {
155 WaitableEvent event(false, false);
156 {
157 base::AutoLock lock(syncer_thread()->lock_);
158 EXPECT_CALL(*listener, OnSyncEngineEvent(
159 Field(&SyncEngineEvent::what_happened,
160 SyncEngineEvent::SYNCER_THREAD_RESUMED))).
161 WillOnce(SignalEvent(&event));
162 }
163 if (!syncer_thread()->RequestResume())
164 return false;
165 return event.TimedWait(max_wait_time_);
166 }
167
168 void PreventThreadFromPolling() {
169 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
170 syncer_thread()->SetSyncerShortPollInterval(poll_interval);
171 }
172
173 // Compare a provided TypePayloadMap to the pending nudge info stored in the
174 // SyncerThread vault.
175 bool CompareNudgeTypesToVault(const syncable::ModelTypePayloadMap& lhs) {
176 const syncable::ModelTypePayloadMap& vault_nudge_types =
177 syncer_thread()->vault_.pending_nudge_types_;
178 return lhs == vault_nudge_types;
179 }
180
181 // Compare a provided ModelTypeBitset to the pending nudge info stored in the
182 // SyncerThread vault. Nudge info in vault must not have any non-empty
183 // payloads.
184 bool CompareNudgeTypesBitSetToVault(const syncable::ModelTypeBitSet& lhs) {
185 syncable::ModelTypePayloadMap model_types_with_payloads =
186 syncable::ModelTypePayloadMapFromBitSet(lhs, std::string());
187 size_t count = 0;
188 for (syncable::ModelTypePayloadMap::const_iterator i =
189 syncer_thread()->vault_.pending_nudge_types_.begin();
190 i != syncer_thread()->vault_.pending_nudge_types_.end();
191 ++i, ++count) {
192 if (!lhs.test(i->first))
193 return false;
194 }
195 if (lhs.count() != count)
196 return false;
197 return true;
198 }
199
200
201 private:
202
203 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) {
204 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED)
205 sync_cycle_ended_event_.Signal();
206 }
207
208 protected:
209 TimeDelta max_wait_time_;
210 SyncSessionContext* context_;
211
212 private:
213 ManuallyOpenedTestDirectorySetterUpper metadb_;
214 scoped_ptr<MockConnectionManager> connection_;
215 scoped_refptr<SyncerThread> syncer_thread_;
216 scoped_refptr<ModelSafeWorker> worker_;
217 base::WaitableEvent sync_cycle_ended_event_;
218 DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest);
219 };
220
221 class SyncShareIntercept
222 : public MockConnectionManager::ResponseCodeOverrideRequestor,
223 public MockConnectionManager::MidCommitObserver {
224 public:
225 SyncShareIntercept() : sync_occured_(false, false),
226 allow_multiple_interceptions_(true) {}
227 virtual ~SyncShareIntercept() {}
228 virtual void Observe() {
229 if (!allow_multiple_interceptions_ && !times_sync_occured_.empty())
230 FAIL() << "Multiple sync shares occured.";
231 times_sync_occured_.push_back(TimeTicks::Now());
232 sync_occured_.Signal();
233 }
234
235 // ResponseCodeOverrideRequestor implementation. This assumes any override
236 // requested is intended to silence the SyncerThread.
237 virtual void OnOverrideComplete() {
238 // We should not see any syncing.
239 allow_multiple_interceptions_ = false;
240 times_sync_occured_.clear();
241 }
242
243 void WaitForSyncShare(int at_least_this_many, TimeDelta max_wait) {
244 while (at_least_this_many-- > 0)
245 sync_occured_.TimedWait(max_wait);
246 }
247 std::vector<TimeTicks> times_sync_occured() const {
248 return times_sync_occured_;
249 }
250
251 void Reset() {
252 allow_multiple_interceptions_ = true;
253 times_sync_occured_.clear();
254 sync_occured_.Reset();
255 }
256 private:
257 std::vector<TimeTicks> times_sync_occured_;
258 base::WaitableEvent sync_occured_;
259 bool allow_multiple_interceptions_;
260 DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept);
261 };
262
263 TEST_F(SyncerThreadTest, Construction) {
264 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL,
265 std::vector<SyncEngineEventListener*>());
266 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
267 }
268
269 TEST_F(SyncerThreadTest, StartStop) {
270 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL,
271 std::vector<SyncEngineEventListener*>());
272 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
273 EXPECT_TRUE(syncer_thread->Start());
274 EXPECT_TRUE(syncer_thread->Stop(2000));
275
276 // Do it again for good measure. I caught some bugs by adding this so
277 // I would recommend keeping it.
278 EXPECT_TRUE(syncer_thread->Start());
279 EXPECT_TRUE(syncer_thread->Stop(2000));
280 }
281
282 TEST(SyncerThread, GetRecommendedDelay) {
283 EXPECT_LE(0, SyncerThread::GetRecommendedDelaySeconds(0));
284 EXPECT_LE(1, SyncerThread::GetRecommendedDelaySeconds(1));
285 EXPECT_LE(50, SyncerThread::GetRecommendedDelaySeconds(50));
286 EXPECT_LE(10, SyncerThread::GetRecommendedDelaySeconds(10));
287 EXPECT_EQ(SyncerThread::kMaxBackoffSeconds,
288 SyncerThread::GetRecommendedDelaySeconds(
289 SyncerThread::kMaxBackoffSeconds));
290 EXPECT_EQ(SyncerThread::kMaxBackoffSeconds,
291 SyncerThread::GetRecommendedDelaySeconds(
292 SyncerThread::kMaxBackoffSeconds+1));
293 }
294
295 TEST_F(SyncerThreadTest, CalculateSyncWaitTime) {
296 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL,
297 std::vector<SyncEngineEventListener*>());
298 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
299 syncer_thread->DisableIdleDetection();
300
301 // Syncer_polling_interval_ is less than max poll interval.
302 TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1);
303
304 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
305
306 // user_idle_ms is less than 10 * (syncer_polling_interval*1000).
307 ASSERT_EQ(syncer_polling_interval.InMilliseconds(),
308 syncer_thread->CalculateSyncWaitTime(1000, 0));
309 ASSERT_EQ(syncer_polling_interval.InMilliseconds(),
310 syncer_thread->CalculateSyncWaitTime(1000, 1));
311
312 // user_idle_ms is ge than 10 * (syncer_polling_interval*1000).
313 int last_poll_time = 2000;
314 ASSERT_TRUE(last_poll_time <=
315 syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000));
316 ASSERT_TRUE(last_poll_time * 3 >=
317 syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000));
318 ASSERT_TRUE(last_poll_time <=
319 syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000));
320 ASSERT_TRUE(last_poll_time * 3 >=
321 syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000));
322
323 // Maximum backoff time should be syncer_max_interval.
324 int near_threshold = SyncerThread::kDefaultMaxPollIntervalMs / 2 - 1;
325 int threshold = SyncerThread::kDefaultMaxPollIntervalMs;
326 int over_threshold = SyncerThread::kDefaultMaxPollIntervalMs + 1;
327 ASSERT_TRUE(near_threshold <=
328 syncer_thread->CalculateSyncWaitTime(near_threshold, 10000));
329 ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs >=
330 syncer_thread->CalculateSyncWaitTime(near_threshold, 10000));
331 ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs ==
332 syncer_thread->CalculateSyncWaitTime(threshold, 10000));
333 ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs ==
334 syncer_thread->CalculateSyncWaitTime(over_threshold, 10000));
335
336 // Possible idle time must be capped by syncer_max_interval.
337 int over_sync_max_interval =
338 SyncerThread::kDefaultMaxPollIntervalMs + 1;
339 syncer_polling_interval = TimeDelta::FromSeconds(
340 over_sync_max_interval / 100); // so 1000* is right
341 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
342 ASSERT_EQ(syncer_polling_interval.InSeconds() * 1000,
343 syncer_thread->CalculateSyncWaitTime(1000, over_sync_max_interval));
344 syncer_polling_interval = TimeDelta::FromSeconds(1);
345 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
346 ASSERT_TRUE(last_poll_time <=
347 syncer_thread->CalculateSyncWaitTime(last_poll_time,
348 over_sync_max_interval));
349 ASSERT_TRUE(last_poll_time * 3 >=
350 syncer_thread->CalculateSyncWaitTime(last_poll_time,
351 over_sync_max_interval));
352 }
353
354 TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
355 // Set up the environment.
356 int user_idle_milliseconds_param = 0;
357 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL,
358 std::vector<SyncEngineEventListener*>());
359 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
360 syncer_thread->DisableIdleDetection();
361 // Hold the lock to appease asserts in code.
362 base::AutoLock lock(syncer_thread->lock_);
363
364 // Notifications disabled should result in a polling interval of
365 // kDefaultShortPollInterval.
366 {
367 context->set_notifications_enabled(false);
368 bool continue_sync_cycle_param = false;
369
370 // No work and no backoff.
371 WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
372 0,
373 &user_idle_milliseconds_param,
374 &continue_sync_cycle_param,
375 false);
376
377 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
378 interval.poll_delta.InSeconds());
379 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
380 ASSERT_FALSE(interval.had_nudge_during_backoff);
381 ASSERT_FALSE(continue_sync_cycle_param);
382
383 // In this case the continue_sync_cycle is turned off.
384 continue_sync_cycle_param = true;
385 interval = syncer_thread->CalculatePollingWaitTime(
386 0,
387 &user_idle_milliseconds_param,
388 &continue_sync_cycle_param,
389 false);
390
391 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
392 interval.poll_delta.InSeconds());
393 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
394 ASSERT_FALSE(interval.had_nudge_during_backoff);
395 ASSERT_FALSE(continue_sync_cycle_param);
396 }
397
398 // Notifications enabled should result in a polling interval of
399 // SyncerThread::kDefaultLongPollIntervalSeconds.
400 {
401 context->set_notifications_enabled(true);
402 bool continue_sync_cycle_param = false;
403
404 // No work and no backoff.
405 WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
406 0,
407 &user_idle_milliseconds_param,
408 &continue_sync_cycle_param,
409 false);
410
411 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
412 interval.poll_delta.InSeconds());
413 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
414 ASSERT_FALSE(interval.had_nudge_during_backoff);
415 ASSERT_FALSE(continue_sync_cycle_param);
416
417 // In this case the continue_sync_cycle is turned off.
418 continue_sync_cycle_param = true;
419 interval = syncer_thread->CalculatePollingWaitTime(
420 0,
421 &user_idle_milliseconds_param,
422 &continue_sync_cycle_param,
423 false);
424
425 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
426 interval.poll_delta.InSeconds());
427 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
428 ASSERT_FALSE(interval.had_nudge_during_backoff);
429 ASSERT_FALSE(continue_sync_cycle_param);
430 }
431
432 // There are two states which can cause a continuation, either the updates
433 // available do not match the updates received, or the unsynced count is
434 // non-zero.
435 {
436 // More server changes remaining to download.
437 context->set_last_snapshot(SessionSnapshotForTest(1, 0));
438 bool continue_sync_cycle_param = false;
439
440 WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
441 0,
442 &user_idle_milliseconds_param,
443 &continue_sync_cycle_param,
444 false);
445
446 ASSERT_LE(0, interval.poll_delta.InSeconds());
447 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
448 ASSERT_FALSE(interval.had_nudge_during_backoff);
449 ASSERT_TRUE(continue_sync_cycle_param);
450
451 continue_sync_cycle_param = false;
452 interval = syncer_thread->CalculatePollingWaitTime(
453 0,
454 &user_idle_milliseconds_param,
455 &continue_sync_cycle_param,
456 false);
457
458 ASSERT_GE(3, interval.poll_delta.InSeconds());
459 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
460 ASSERT_FALSE(interval.had_nudge_during_backoff);
461 ASSERT_TRUE(continue_sync_cycle_param);
462
463 interval = syncer_thread->CalculatePollingWaitTime(
464 0,
465 &user_idle_milliseconds_param,
466 &continue_sync_cycle_param,
467 false);
468
469 ASSERT_LE(0, interval.poll_delta.InSeconds());
470 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
471 ASSERT_FALSE(interval.had_nudge_during_backoff);
472
473 interval = syncer_thread->CalculatePollingWaitTime(
474 0,
475 &user_idle_milliseconds_param,
476 &continue_sync_cycle_param,
477 false);
478
479 ASSERT_GE(2, interval.poll_delta.InSeconds());
480 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
481 ASSERT_FALSE(interval.had_nudge_during_backoff);
482 ASSERT_TRUE(continue_sync_cycle_param);
483
484 // Now simulate no more server changes remaining.
485 context->set_last_snapshot(SessionSnapshotForTest(0, 0));
486 interval = syncer_thread->CalculatePollingWaitTime(
487 0,
488 &user_idle_milliseconds_param,
489 &continue_sync_cycle_param,
490 false);
491
492 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
493 interval.poll_delta.InSeconds());
494 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
495 ASSERT_FALSE(interval.had_nudge_during_backoff);
496 ASSERT_FALSE(continue_sync_cycle_param);
497 }
498
499 {
500 // Now try with unsynced local items.
501 context->set_last_snapshot(SessionSnapshotForTest(0, 1));
502 bool continue_sync_cycle_param = false;
503
504 WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
505 0,
506 &user_idle_milliseconds_param,
507 &continue_sync_cycle_param,
508 false);
509
510 ASSERT_LE(0, interval.poll_delta.InSeconds());
511 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
512 ASSERT_FALSE(interval.had_nudge_during_backoff);
513 ASSERT_TRUE(continue_sync_cycle_param);
514
515 continue_sync_cycle_param = false;
516 interval = syncer_thread->CalculatePollingWaitTime(
517 0,
518 &user_idle_milliseconds_param,
519 &continue_sync_cycle_param,
520 false);
521
522 ASSERT_GE(2, interval.poll_delta.InSeconds());
523 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
524 ASSERT_FALSE(interval.had_nudge_during_backoff);
525 ASSERT_TRUE(continue_sync_cycle_param);
526
527 context->set_last_snapshot(SessionSnapshotForTest(0, 0));
528 interval = syncer_thread->CalculatePollingWaitTime(
529 4,
530 &user_idle_milliseconds_param,
531 &continue_sync_cycle_param,
532 false);
533
534 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
535 interval.poll_delta.InSeconds());
536 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
537 ASSERT_FALSE(interval.had_nudge_during_backoff);
538 ASSERT_FALSE(continue_sync_cycle_param);
539 }
540
541 // Regression for exponential backoff reset when the syncer is nudged.
542 {
543 context->set_last_snapshot(SessionSnapshotForTest(0, 1));
544 bool continue_sync_cycle_param = false;
545
546 // Expect move from default polling interval to exponential backoff due to
547 // unsynced_count != 0.
548 WaitInterval interval = syncer_thread->CalculatePollingWaitTime(
549 3600,
550 &user_idle_milliseconds_param,
551 &continue_sync_cycle_param,
552 false);
553
554 ASSERT_LE(0, interval.poll_delta.InSeconds());
555 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
556 ASSERT_FALSE(interval.had_nudge_during_backoff);
557 ASSERT_TRUE(continue_sync_cycle_param);
558
559 continue_sync_cycle_param = false;
560 interval = syncer_thread->CalculatePollingWaitTime(
561 3600,
562 &user_idle_milliseconds_param,
563 &continue_sync_cycle_param,
564 false);
565
566 ASSERT_GE(2, interval.poll_delta.InSeconds());
567 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
568 ASSERT_FALSE(interval.had_nudge_during_backoff);
569 ASSERT_TRUE(continue_sync_cycle_param);
570
571 // Expect exponential backoff.
572 interval = syncer_thread->CalculatePollingWaitTime(
573 2,
574 &user_idle_milliseconds_param,
575 &continue_sync_cycle_param,
576 false);
577
578 ASSERT_LE(2, interval.poll_delta.InSeconds());
579 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
580 ASSERT_FALSE(interval.had_nudge_during_backoff);
581 ASSERT_TRUE(continue_sync_cycle_param);
582
583 interval = syncer_thread->CalculatePollingWaitTime(
584 2,
585 &user_idle_milliseconds_param,
586 &continue_sync_cycle_param,
587 false);
588
589 ASSERT_GE(6, interval.poll_delta.InSeconds());
590 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
591 ASSERT_FALSE(interval.had_nudge_during_backoff);
592 ASSERT_TRUE(continue_sync_cycle_param);
593
594 syncer_thread->vault_.current_wait_interval_ = interval;
595
596 interval = syncer_thread->CalculatePollingWaitTime(
597 static_cast<int>(interval.poll_delta.InSeconds()),
598 &user_idle_milliseconds_param,
599 &continue_sync_cycle_param,
600 true);
601
602 // Don't change poll on a failed nudge during backoff.
603 ASSERT_TRUE(syncer_thread->vault_.current_wait_interval_.poll_delta ==
604 interval.poll_delta);
605 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
606 ASSERT_TRUE(interval.had_nudge_during_backoff);
607 ASSERT_TRUE(continue_sync_cycle_param);
608
609 // If we got a nudge and we weren't in backoff mode, we see exponential
610 // backoff.
611 syncer_thread->vault_.current_wait_interval_.mode = WaitInterval::NORMAL;
612 interval = syncer_thread->CalculatePollingWaitTime(
613 2,
614 &user_idle_milliseconds_param,
615 &continue_sync_cycle_param,
616 true);
617
618 // 5 and 3 are bounds on the backoff randomization formula given input of 2.
619 ASSERT_GE(5, interval.poll_delta.InSeconds());
620 ASSERT_LE(3, interval.poll_delta.InSeconds());
621 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
622 ASSERT_FALSE(interval.had_nudge_during_backoff);
623 ASSERT_TRUE(continue_sync_cycle_param);
624
625 // And if another interval expires, we get a bigger backoff.
626 WaitInterval new_interval = syncer_thread->CalculatePollingWaitTime(
627 static_cast<int>(interval.poll_delta.InSeconds()),
628 &user_idle_milliseconds_param,
629 &continue_sync_cycle_param,
630 false);
631
632 ASSERT_GE(12, new_interval.poll_delta.InSeconds());
633 ASSERT_LE(5, new_interval.poll_delta.InSeconds());
634 ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode);
635 ASSERT_FALSE(new_interval.had_nudge_during_backoff);
636 ASSERT_TRUE(continue_sync_cycle_param);
637
638 // A nudge resets the continue_sync_cycle_param value, so our backoff
639 // should return to the minimum.
640 continue_sync_cycle_param = false;
641 interval = syncer_thread->CalculatePollingWaitTime(
642 3600,
643 &user_idle_milliseconds_param,
644 &continue_sync_cycle_param,
645 true);
646
647 ASSERT_LE(0, interval.poll_delta.InSeconds());
648 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
649 ASSERT_FALSE(interval.had_nudge_during_backoff);
650 ASSERT_TRUE(continue_sync_cycle_param);
651
652 continue_sync_cycle_param = false;
653 interval = syncer_thread->CalculatePollingWaitTime(
654 3600,
655 &user_idle_milliseconds_param,
656 &continue_sync_cycle_param,
657 true);
658
659 ASSERT_GE(2, interval.poll_delta.InSeconds());
660 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
661 ASSERT_FALSE(interval.had_nudge_during_backoff);
662 ASSERT_TRUE(continue_sync_cycle_param);
663
664 // Setting unsynced_count = 0 returns us to the default polling interval.
665 context->set_last_snapshot(SessionSnapshotForTest(0, 0));
666 interval = syncer_thread->CalculatePollingWaitTime(
667 4,
668 &user_idle_milliseconds_param,
669 &continue_sync_cycle_param,
670 true);
671
672 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
673 interval.poll_delta.InSeconds());
674 ASSERT_EQ(WaitInterval::NORMAL, interval.mode);
675 ASSERT_FALSE(interval.had_nudge_during_backoff);
676 ASSERT_FALSE(continue_sync_cycle_param);
677 }
678 }
679
680 TEST_F(SyncerThreadWithSyncerTest, Polling) {
681 SyncShareIntercept interceptor;
682 connection()->SetMidCommitObserver(&interceptor);
683
684 const TimeDelta poll_interval = TimeDelta::FromSeconds(1);
685 syncer_thread()->SetSyncerShortPollInterval(poll_interval);
686 EXPECT_TRUE(syncer_thread()->Start());
687
688 metadb()->Open();
689 syncer_thread()->CreateSyncer(metadb()->name());
690
691 TimeDelta two_polls = poll_interval + poll_interval;
692 // We could theoretically return immediately from the wait if the interceptor
693 // was already signaled for a SyncShare (the first one comes quick).
694 interceptor.WaitForSyncShare(1, two_polls);
695 EXPECT_FALSE(interceptor.times_sync_occured().empty());
696
697 // Wait for at least 2 more SyncShare operations.
698 interceptor.WaitForSyncShare(2, two_polls);
699 EXPECT_TRUE(syncer_thread()->Stop(2000));
700
701 // Now analyze the run.
702 std::vector<TimeTicks> data = interceptor.times_sync_occured();
703
704 EXPECT_GE(data.size(), static_cast<unsigned int>(3));
705 for (unsigned int i = 0; i < data.size() - 1; i++) {
706 TimeTicks optimal_next_sync = data[i] + poll_interval;
707 EXPECT_TRUE(data[i + 1] >= optimal_next_sync);
708 // This should be reliable, as there are no blocking or I/O operations
709 // except the explicit 2 second wait, so if it takes longer than this
710 // there is a problem.
711 EXPECT_TRUE(data[i + 1] < optimal_next_sync + poll_interval);
712 }
713 }
714
715 TEST_F(SyncerThreadWithSyncerTest, Nudge) {
716 SyncShareIntercept interceptor;
717 connection()->SetMidCommitObserver(&interceptor);
718 // We don't want a poll to happen during this test (except the first one).
719 PreventThreadFromPolling();
720 EXPECT_TRUE(syncer_thread()->Start());
721 metadb()->Open();
722 syncer_thread()->CreateSyncer(metadb()->name());
723 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
724 interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
725
726 EXPECT_EQ(static_cast<unsigned int>(1),
727 interceptor.times_sync_occured().size());
728 // The SyncerThread should be waiting for the poll now. Nudge it to sync
729 // immediately (5ms).
730 syncer_thread()->NudgeSyncer(5, SyncerThread::kUnknown);
731 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
732 EXPECT_EQ(static_cast<unsigned int>(2),
733 interceptor.times_sync_occured().size());
734
735 // SyncerThread should be waiting again. Signal it to stop.
736 EXPECT_TRUE(syncer_thread()->Stop(2000));
737 }
738
739 TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypes) {
740 SyncShareIntercept interceptor;
741 connection()->SetMidCommitObserver(&interceptor);
742 // We don't want a poll to happen during this test (except the first one).
743 PreventThreadFromPolling();
744 EXPECT_TRUE(syncer_thread()->Start());
745 metadb()->Open();
746 syncer_thread()->CreateSyncer(metadb()->name());
747 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
748 interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
749 EXPECT_EQ(static_cast<unsigned int>(1),
750 interceptor.times_sync_occured().size());
751
752 // The SyncerThread should be waiting for the poll now. Nudge it to sync
753 // immediately (5ms).
754 syncable::ModelTypeBitSet model_types;
755 model_types[syncable::BOOKMARKS] = true;
756
757 // Paused so we can verify the nudge types safely.
758 syncer_thread()->RequestPause();
759 syncer_thread()->NudgeSyncerWithDataTypes(5,
760 SyncerThread::kUnknown,
761 model_types);
762 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types));
763 syncer_thread()->RequestResume();
764
765 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
766 EXPECT_EQ(static_cast<unsigned int>(2),
767 interceptor.times_sync_occured().size());
768
769 // SyncerThread should be waiting again. Signal it to stop.
770 EXPECT_TRUE(syncer_thread()->Stop(2000));
771 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty());
772 }
773
774 TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypesCoalesced) {
775 SyncShareIntercept interceptor;
776 connection()->SetMidCommitObserver(&interceptor);
777 // We don't want a poll to happen during this test (except the first one).
778 PreventThreadFromPolling();
779 EXPECT_TRUE(syncer_thread()->Start());
780 metadb()->Open();
781 syncer_thread()->CreateSyncer(metadb()->name());
782 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
783 interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
784 EXPECT_EQ(static_cast<unsigned int>(1),
785 interceptor.times_sync_occured().size());
786
787 // The SyncerThread should be waiting for the poll now. Nudge it to sync
788 // immediately (5ms).
789 syncable::ModelTypeBitSet model_types;
790 model_types[syncable::BOOKMARKS] = true;
791
792 // Paused so we can verify the nudge types safely.
793 syncer_thread()->RequestPause();
794 syncer_thread()->NudgeSyncerWithDataTypes(100,
795 SyncerThread::kUnknown,
796 model_types);
797 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types));
798
799 model_types[syncable::BOOKMARKS] = false;
800 model_types[syncable::AUTOFILL] = true;
801 syncer_thread()->NudgeSyncerWithDataTypes(0,
802 SyncerThread::kUnknown,
803 model_types);
804
805 // Reset BOOKMARKS for expectations.
806 model_types[syncable::BOOKMARKS] = true;
807 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types));
808
809 syncer_thread()->RequestResume();
810
811 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
812 EXPECT_EQ(static_cast<unsigned int>(2),
813 interceptor.times_sync_occured().size());
814
815 // SyncerThread should be waiting again. Signal it to stop.
816 EXPECT_TRUE(syncer_thread()->Stop(2000));
817 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty());
818 }
819
820 TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloads) {
821 SyncShareIntercept interceptor;
822 connection()->SetMidCommitObserver(&interceptor);
823 // We don't want a poll to happen during this test (except the first one).
824 PreventThreadFromPolling();
825 EXPECT_TRUE(syncer_thread()->Start());
826 metadb()->Open();
827 syncer_thread()->CreateSyncer(metadb()->name());
828 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
829 interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
830 EXPECT_EQ(static_cast<unsigned int>(1),
831 interceptor.times_sync_occured().size());
832
833 // The SyncerThread should be waiting for the poll now. Nudge it to sync
834 // immediately (5ms).
835 syncable::ModelTypePayloadMap nudge_types;
836 nudge_types[syncable::BOOKMARKS] = "test";
837 connection()->ExpectGetUpdatesRequestPayloads(nudge_types);
838
839 // Paused so we can verify the nudge types safely.
840 syncer_thread()->RequestPause();
841 syncer_thread()->NudgeSyncerWithPayloads(5,
842 SyncerThread::kUnknown,
843 nudge_types);
844 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types));
845 syncer_thread()->RequestResume();
846
847 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
848 EXPECT_EQ(static_cast<unsigned int>(2),
849 interceptor.times_sync_occured().size());
850
851 // SyncerThread should be waiting again. Signal it to stop.
852 EXPECT_TRUE(syncer_thread()->Stop(2000));
853 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty());
854 }
855
856 TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloadsCoalesced) {
857 SyncShareIntercept interceptor;
858 connection()->SetMidCommitObserver(&interceptor);
859 // We don't want a poll to happen during this test (except the first one).
860 PreventThreadFromPolling();
861 EXPECT_TRUE(syncer_thread()->Start());
862 metadb()->Open();
863 syncer_thread()->CreateSyncer(metadb()->name());
864 const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
865 interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
866 EXPECT_EQ(static_cast<unsigned int>(1),
867 interceptor.times_sync_occured().size());
868
869 // The SyncerThread should be waiting for the poll now. Nudge it to sync
870 // immediately (5ms).
871 syncable::ModelTypePayloadMap nudge_types;
872 nudge_types[syncable::BOOKMARKS] = "books";
873
874 // Paused so we can verify the nudge types safely.
875 syncer_thread()->RequestPause();
876 syncer_thread()->NudgeSyncerWithPayloads(100,
877 SyncerThread::kUnknown,
878 nudge_types);
879 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types));
880
881 nudge_types.erase(syncable::BOOKMARKS);
882 nudge_types[syncable::AUTOFILL] = "auto";
883 syncer_thread()->NudgeSyncerWithPayloads(0,
884 SyncerThread::kUnknown,
885 nudge_types);
886
887 // Reset BOOKMARKS for expectations.
888 nudge_types[syncable::BOOKMARKS] = "books";
889 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types));
890 connection()->ExpectGetUpdatesRequestPayloads(nudge_types);
891
892 syncer_thread()->RequestResume();
893
894 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
895 EXPECT_EQ(static_cast<unsigned int>(2),
896 interceptor.times_sync_occured().size());
897
898 // SyncerThread should be waiting again. Signal it to stop.
899 EXPECT_TRUE(syncer_thread()->Stop(2000));
900 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty());
901 }
902
903 TEST_F(SyncerThreadWithSyncerTest, Throttling) {
904 SyncShareIntercept interceptor;
905 connection()->SetMidCommitObserver(&interceptor);
906 const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10);
907 syncer_thread()->SetSyncerShortPollInterval(poll_interval);
908
909 EXPECT_TRUE(syncer_thread()->Start());
910 metadb()->Open();
911 syncer_thread()->CreateSyncer(metadb()->name());
912
913 // Wait for some healthy syncing.
914 interceptor.WaitForSyncShare(4, poll_interval + poll_interval);
915
916 // Tell the server to throttle a single request, which should be all it takes
917 // to silence our syncer (for 2 hours, so we shouldn't hit that in this test).
918 // This will atomically visit the interceptor so it can switch to throttled
919 // mode and fail on multiple requests.
920 connection()->ThrottleNextRequest(&interceptor);
921
922 // Try to trigger a sync (we have a really short poll interval already).
923 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
924 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
925
926 // Wait until the syncer thread reports that it is throttled. Any further
927 // sync share interceptions will result in failure. If things are broken,
928 // we may never halt.
929 ASSERT_TRUE(WaitForThrottle());
930 EXPECT_TRUE(syncer_thread()->IsSyncingCurrentlySilenced());
931
932 EXPECT_TRUE(syncer_thread()->Stop(2000));
933 }
934
935 TEST_F(SyncerThreadWithSyncerTest, StopSyncPermanently) {
936 // The SyncerThread should request an exit from the Syncer and set
937 // conditions for termination.
938 const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10);
939 syncer_thread()->SetSyncerShortPollInterval(poll_interval);
940
941 ListenerMock listener;
942 WaitableEvent sync_cycle_ended_event(false, false);
943 WaitableEvent syncer_thread_exiting_event(false, false);
944 TestScopedSessionEventListener reg(context_, &listener);
945
946 EXPECT_CALL(listener, OnSyncEngineEvent(
947 Field(&SyncEngineEvent::what_happened,
948 SyncEngineEvent::STATUS_CHANGED))).
949 Times(AnyNumber());
950
951 EXPECT_CALL(listener, OnSyncEngineEvent(
952 Field(&SyncEngineEvent::what_happened,
953 SyncEngineEvent::SYNC_CYCLE_ENDED))).
954 Times(AnyNumber()).
955 WillOnce(SignalEvent(&sync_cycle_ended_event));
956
957 EXPECT_CALL(listener, OnSyncEngineEvent(
958 Field(&SyncEngineEvent::what_happened,
959 SyncEngineEvent::STOP_SYNCING_PERMANENTLY)));
960 EXPECT_CALL(listener, OnSyncEngineEvent(
961 Field(&SyncEngineEvent::what_happened,
962 SyncEngineEvent::SYNCER_THREAD_EXITING))).
963 WillOnce(SignalEvent(&syncer_thread_exiting_event));
964
965 EXPECT_TRUE(syncer_thread()->Start());
966 metadb()->Open();
967 syncer_thread()->CreateSyncer(metadb()->name());
968 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
969
970 connection()->set_store_birthday("NotYourLuckyDay");
971 ASSERT_TRUE(syncer_thread_exiting_event.TimedWait(max_wait_time_));
972 EXPECT_TRUE(syncer_thread()->Stop(0));
973 }
974
975 TEST_F(SyncerThreadWithSyncerTest, AuthInvalid) {
976 SyncShareIntercept interceptor;
977 connection()->SetMidCommitObserver(&interceptor);
978 const TimeDelta poll_interval = TimeDelta::FromMilliseconds(1);
979
980 syncer_thread()->SetSyncerShortPollInterval(poll_interval);
981 EXPECT_TRUE(syncer_thread()->Start());
982 metadb()->Open();
983 syncer_thread()->CreateSyncer(metadb()->name());
984
985 // Wait for some healthy syncing.
986 interceptor.WaitForSyncShare(2, TimeDelta::FromSeconds(10));
987 EXPECT_GE(interceptor.times_sync_occured().size(), 2U);
988
989 // Atomically start returning auth invalid and set the interceptor to fail
990 // on any sync.
991 connection()->FailWithAuthInvalid(&interceptor);
992 WaitForDisconnect();
993
994 // Try to trigger a sync (the interceptor will assert if one occurs).
995 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
996 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
997
998 // Wait several poll intervals but don't expect any syncing besides the cycle
999 // that lost the connection.
1000 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
1001 EXPECT_EQ(1U, interceptor.times_sync_occured().size());
1002
1003 // Simulate a valid re-authentication and expect resumption of syncing.
1004 interceptor.Reset();
1005 ASSERT_TRUE(interceptor.times_sync_occured().empty());
1006 connection()->StopFailingWithAuthInvalid(NULL);
1007 ServerConnectionEvent e = {ServerConnectionEvent::STATUS_CHANGED,
1008 HttpResponse::SERVER_CONNECTION_OK,
1009 true};
1010 connection()->channel()->NotifyListeners(e);
1011
1012 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(10));
1013 EXPECT_FALSE(interceptor.times_sync_occured().empty());
1014
1015 EXPECT_TRUE(syncer_thread()->Stop(2000));
1016 }
1017
1018 // TODO(zea): Disabled, along with PauseWhenNotConnected, due to stalling on
1019 // windows, preventing further sync unit tests from running. See crbug/39070.
1020 TEST_F(SyncerThreadWithSyncerTest, DISABLED_Pause) {
1021 WaitableEvent sync_cycle_ended_event(false, false);
1022 WaitableEvent paused_event(false, false);
1023 WaitableEvent resumed_event(false, false);
1024 PreventThreadFromPolling();
1025
1026 ListenerMock listener;
1027 TestScopedSessionEventListener reg(context_, &listener);
1028 EXPECT_CALL(listener, OnSyncEngineEvent(
1029 Field(&SyncEngineEvent::what_happened,
1030 SyncEngineEvent::STATUS_CHANGED))).
1031 Times(AnyNumber());
1032
1033 // Wait for the initial sync to complete.
1034 EXPECT_CALL(listener, OnSyncEngineEvent(
1035 Field(&SyncEngineEvent::what_happened,
1036 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1037 WillOnce(SignalEvent(&sync_cycle_ended_event));
1038 EXPECT_CALL(listener, OnSyncEngineEvent(
1039 Field(&SyncEngineEvent::what_happened,
1040 SyncEngineEvent::SYNCER_THREAD_EXITING)));
1041
1042 ASSERT_TRUE(syncer_thread()->Start());
1043 metadb()->Open();
1044 syncer_thread()->CreateSyncer(metadb()->name());
1045 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1046
1047 // Request a pause.
1048 ASSERT_TRUE(Pause(&listener));
1049
1050 // Resuming the pause.
1051 ASSERT_TRUE(Resume(&listener));
1052
1053 // Not paused, should fail.
1054 EXPECT_FALSE(syncer_thread()->RequestResume());
1055
1056 // Request a pause.
1057 ASSERT_TRUE(Pause(&listener));
1058
1059 // Nudge the syncer, this should do nothing while we are paused.
1060 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
1061
1062 // Resuming will cause the nudge to be processed and a sync cycle to run.
1063 EXPECT_CALL(listener, OnSyncEngineEvent(
1064 Field(&SyncEngineEvent::what_happened,
1065 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1066 WillOnce(SignalEvent(&sync_cycle_ended_event));
1067 ASSERT_TRUE(Resume(&listener));
1068 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1069
1070 EXPECT_TRUE(syncer_thread()->Stop(2000));
1071 }
1072
1073 TEST_F(SyncerThreadWithSyncerTest, StartWhenNotConnected) {
1074 WaitableEvent sync_cycle_ended_event(false, false);
1075 WaitableEvent event(false, false);
1076 ListenerMock listener;
1077 TestScopedSessionEventListener reg(context_, &listener);
1078 PreventThreadFromPolling();
1079
1080 EXPECT_CALL(listener, OnSyncEngineEvent(
1081 Field(&SyncEngineEvent::what_happened,
1082 SyncEngineEvent::STATUS_CHANGED))).
1083 Times(AnyNumber());
1084 EXPECT_CALL(listener, OnSyncEngineEvent(
1085 Field(&SyncEngineEvent::what_happened,
1086 SyncEngineEvent::SYNCER_THREAD_EXITING)));
1087
1088 connection()->SetServerNotReachable();
1089 metadb()->Open();
1090 syncer_thread()->CreateSyncer(metadb()->name());
1091
1092 // Syncer thread will always go through once cycle at the start,
1093 // then it will wait for a connection.
1094 EXPECT_CALL(listener, OnSyncEngineEvent(
1095 Field(&SyncEngineEvent::what_happened,
1096 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1097 WillOnce(SignalEvent(&sync_cycle_ended_event));
1098 EXPECT_CALL(listener, OnSyncEngineEvent(
1099 Field(&SyncEngineEvent::what_happened,
1100 SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))).
1101 WillOnce(SignalEvent(&event));
1102 ASSERT_TRUE(syncer_thread()->Start());
1103 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1104 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1105
1106 // Connect, will put the syncer thread into its usually poll wait.
1107 EXPECT_CALL(listener, OnSyncEngineEvent(
1108 Field(&SyncEngineEvent::what_happened,
1109 SyncEngineEvent::SYNCER_THREAD_CONNECTED))).
1110 WillOnce(SignalEvent(&event));
1111 connection()->SetServerReachable();
1112 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1113
1114 // Nudge the syncer to complete a cycle.
1115 EXPECT_CALL(listener, OnSyncEngineEvent(
1116 Field(&SyncEngineEvent::what_happened,
1117 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1118 WillOnce(SignalEvent(&sync_cycle_ended_event));
1119 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
1120 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1121
1122 EXPECT_TRUE(syncer_thread()->Stop(2000));
1123 }
1124
1125 // See TODO comment on the "Pause" test above.
1126 TEST_F(SyncerThreadWithSyncerTest, DISABLED_PauseWhenNotConnected) {
1127 WaitableEvent sync_cycle_ended_event(false, false);
1128 WaitableEvent event(false, false);
1129 ListenerMock listener;
1130 TestScopedSessionEventListener reg(context_, &listener);
1131 PreventThreadFromPolling();
1132
1133 EXPECT_CALL(listener, OnSyncEngineEvent(
1134 Field(&SyncEngineEvent::what_happened,
1135 SyncEngineEvent::STATUS_CHANGED))).
1136 Times(AnyNumber());
1137
1138 // Put the thread into a "waiting for connection" state.
1139 connection()->SetServerNotReachable();
1140 EXPECT_CALL(listener, OnSyncEngineEvent(
1141 Field(&SyncEngineEvent::what_happened,
1142 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1143 WillOnce(SignalEvent(&sync_cycle_ended_event));
1144 EXPECT_CALL(listener, OnSyncEngineEvent(
1145 Field(&SyncEngineEvent::what_happened,
1146 SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))).
1147 WillOnce(SignalEvent(&event));
1148 metadb()->Open();
1149 syncer_thread()->CreateSyncer(metadb()->name());
1150
1151 ASSERT_TRUE(syncer_thread()->Start());
1152 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1153 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1154
1155 // Pause and resume the thread while waiting for a connection.
1156 ASSERT_TRUE(Pause(&listener));
1157 ASSERT_TRUE(Resume(&listener));
1158
1159 // Make a connection and let the syncer cycle.
1160 EXPECT_CALL(listener, OnSyncEngineEvent(
1161 Field(&SyncEngineEvent::what_happened,
1162 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1163 WillOnce(SignalEvent(&sync_cycle_ended_event));
1164 EXPECT_CALL(listener, OnSyncEngineEvent(
1165 Field(&SyncEngineEvent::what_happened,
1166 SyncEngineEvent::SYNCER_THREAD_CONNECTED))).
1167 WillOnce(SignalEvent(&event));
1168 connection()->SetServerReachable();
1169 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1170 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
1171 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1172
1173 // Disconnect and get into the waiting for a connection state.
1174 EXPECT_CALL(listener, OnSyncEngineEvent(
1175 Field(&SyncEngineEvent::what_happened,
1176 SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))).
1177 WillOnce(SignalEvent(&event));
1178 connection()->SetServerNotReachable();
1179 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1180
1181 // Pause so we can test getting a connection while paused.
1182 ASSERT_TRUE(Pause(&listener));
1183
1184 // Get a connection then resume.
1185 EXPECT_CALL(listener, OnSyncEngineEvent(
1186 Field(&SyncEngineEvent::what_happened,
1187 SyncEngineEvent::SYNCER_THREAD_CONNECTED))).
1188 WillOnce(SignalEvent(&event));
1189 connection()->SetServerReachable();
1190 ASSERT_TRUE(event.TimedWait(max_wait_time_));
1191
1192 ASSERT_TRUE(Resume(&listener));
1193
1194 // Cycle the syncer to show we are not longer paused.
1195 EXPECT_CALL(listener, OnSyncEngineEvent(
1196 Field(&SyncEngineEvent::what_happened,
1197 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1198 WillOnce(SignalEvent(&sync_cycle_ended_event));
1199 EXPECT_CALL(listener, OnSyncEngineEvent(
1200 Field(&SyncEngineEvent::what_happened,
1201 SyncEngineEvent::SYNCER_THREAD_EXITING)));
1202
1203 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown);
1204 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1205
1206 EXPECT_TRUE(syncer_thread()->Stop(2000));
1207 }
1208
1209 TEST_F(SyncerThreadWithSyncerTest, PauseResumeWhenNotRunning) {
1210 WaitableEvent sync_cycle_ended_event(false, false);
1211 WaitableEvent event(false, false);
1212 ListenerMock listener;
1213 TestScopedSessionEventListener reg(context_, &listener);
1214 PreventThreadFromPolling();
1215
1216 EXPECT_CALL(listener, OnSyncEngineEvent(
1217 Field(&SyncEngineEvent::what_happened,
1218 SyncEngineEvent::STATUS_CHANGED))).
1219 Times(AnyNumber());
1220
1221 // Pause and resume the syncer while not running
1222 ASSERT_TRUE(Pause(&listener));
1223 ASSERT_TRUE(Resume(&listener));
1224
1225 // Pause the thread then start the syncer.
1226 ASSERT_TRUE(Pause(&listener));
1227 metadb()->Open();
1228 syncer_thread()->CreateSyncer(metadb()->name());
1229 ASSERT_TRUE(syncer_thread()->Start());
1230
1231 // Resume and let the syncer cycle.
1232 EXPECT_CALL(listener, OnSyncEngineEvent(
1233 Field(&SyncEngineEvent::what_happened,
1234 SyncEngineEvent::SYNC_CYCLE_ENDED))).
1235 WillOnce(SignalEvent(&sync_cycle_ended_event));
1236 EXPECT_CALL(listener, OnSyncEngineEvent(
1237 Field(&SyncEngineEvent::what_happened,
1238 SyncEngineEvent::SYNCER_THREAD_EXITING)));
1239
1240 ASSERT_TRUE(Resume(&listener));
1241 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
1242 EXPECT_TRUE(syncer_thread()->Stop(2000));
1243 }
1244
1245 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_thread_adapter.cc ('k') | chrome/browser/sync/engine/syncer_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698