Index: chrome/browser/sync/engine/syncer_thread_unittest.cc |
diff --git a/chrome/browser/sync/engine/syncer_thread_unittest.cc b/chrome/browser/sync/engine/syncer_thread_unittest.cc |
index faa0e9b78403f157c5420b4d5a715a6dc7420c3f..7a37f389f077027162703503423aa052c279e162 100644 |
--- a/chrome/browser/sync/engine/syncer_thread_unittest.cc |
+++ b/chrome/browser/sync/engine/syncer_thread_unittest.cc |
@@ -1,1245 +1,3 @@ |
// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
- |
-#include <list> |
-#include <map> |
- |
-#include "base/memory/scoped_ptr.h" |
-#include "base/synchronization/lock.h" |
-#include "base/time.h" |
-#include "base/synchronization/waitable_event.h" |
-#include "chrome/browser/sync/engine/model_safe_worker.h" |
-#include "chrome/browser/sync/engine/syncer_thread.h" |
-#include "chrome/browser/sync/engine/syncer_types.h" |
-#include "chrome/browser/sync/sessions/sync_session_context.h" |
-#include "chrome/browser/sync/util/channel.h" |
-#include "chrome/test/sync/engine/mock_connection_manager.h" |
-#include "chrome/test/sync/engine/test_directory_setter_upper.h" |
-#include "chrome/test/sync/sessions/test_scoped_session_event_listener.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-using base::TimeTicks; |
-using base::TimeDelta; |
-using base::WaitableEvent; |
-using testing::_; |
-using testing::AnyNumber; |
-using testing::Field; |
- |
-namespace browser_sync { |
-using sessions::ErrorCounters; |
-using sessions::TestScopedSessionEventListener; |
-using sessions::SyncSessionContext; |
-using sessions::SyncSessionSnapshot; |
-using sessions::SyncerStatus; |
- |
-typedef testing::Test SyncerThreadTest; |
-typedef SyncerThread::WaitInterval WaitInterval; |
- |
-ACTION_P(SignalEvent, event) { |
- event->Signal(); |
-} |
- |
-SyncSessionSnapshot SessionSnapshotForTest( |
- int64 num_server_changes_remaining, |
- int64 unsynced_count) { |
- std::string download_progress_markers[syncable::MODEL_TYPE_COUNT]; |
- for (int i = syncable::FIRST_REAL_MODEL_TYPE; |
- i < syncable::MODEL_TYPE_COUNT; |
- ++i) { |
- syncable::ModelType type(syncable::ModelTypeFromInt(i)); |
- sync_pb::DataTypeProgressMarker token; |
- token.set_data_type_id( |
- syncable::GetExtensionFieldNumberFromModelType(type)); |
- token.set_token("foobar"); |
- token.SerializeToString(&download_progress_markers[i]); |
- } |
- return SyncSessionSnapshot(SyncerStatus(), ErrorCounters(), |
- num_server_changes_remaining, false, |
- syncable::ModelTypeBitSet(), download_progress_markers, |
- false, false, unsynced_count, 0, false, sessions::SyncSourceInfo()); |
-} |
- |
-class ListenerMock : public SyncEngineEventListener { |
- public: |
- MOCK_METHOD1(OnSyncEngineEvent, void(const SyncEngineEvent&)); |
-}; |
- |
-class SyncerThreadWithSyncerTest : public testing::Test, |
- public ModelSafeWorkerRegistrar, |
- public SyncEngineEventListener { |
- public: |
- SyncerThreadWithSyncerTest() |
- : max_wait_time_(TimeDelta::FromSeconds(10)), |
- sync_cycle_ended_event_(false, false) {} |
- virtual void SetUp() { |
- metadb_.SetUp(); |
- connection_.reset(new MockConnectionManager(metadb_.manager(), |
- metadb_.name())); |
- worker_ = new ModelSafeWorker(); |
- std::vector<SyncEngineEventListener*> listeners; |
- listeners.push_back(this); |
- context_ = new SyncSessionContext(connection_.get(), metadb_.manager(), |
- this, listeners); |
- context_->set_account_name(metadb_.name()); |
- syncer_thread_ = new SyncerThread(context_); |
- syncer_thread_->SetConnected(true); |
- syncable::ModelTypeBitSet expected_types; |
- expected_types[syncable::BOOKMARKS] = true; |
- connection_->ExpectGetUpdatesRequestTypes(expected_types); |
- } |
- virtual void TearDown() { |
- context_ = NULL; |
- syncer_thread_ = NULL; |
- connection_.reset(); |
- metadb_.TearDown(); |
- } |
- |
- // ModelSafeWorkerRegistrar implementation. |
- virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) { |
- out->push_back(worker_.get()); |
- } |
- |
- virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { |
- // We're just testing the sync engine here, so we shunt everything to |
- // the SyncerThread. |
- (*out)[syncable::BOOKMARKS] = GROUP_PASSIVE; |
- } |
- |
- ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; } |
- MockConnectionManager* connection() { return connection_.get(); } |
- SyncerThread* syncer_thread() { return syncer_thread_; } |
- |
- // Waits an indefinite amount of sync cycles for the syncer thread to become |
- // throttled. Only call this if a throttle is supposed to occur! |
- bool WaitForThrottle() { |
- int max_cycles = 5; |
- while (max_cycles && !syncer_thread()->IsSyncingCurrentlySilenced()) { |
- sync_cycle_ended_event_.TimedWait(max_wait_time_); |
- max_cycles--; |
- } |
- |
- return syncer_thread()->IsSyncingCurrentlySilenced(); |
- } |
- |
- void WaitForDisconnect() { |
- // Wait for the SyncerThread to detect loss of connection, up to a max of |
- // 10 seconds to timeout the test. |
- base::AutoLock lock(syncer_thread()->lock_); |
- TimeTicks start = TimeTicks::Now(); |
- TimeDelta ten_seconds = TimeDelta::FromSeconds(10); |
- while (syncer_thread()->vault_.connected_) { |
- syncer_thread()->vault_field_changed_.TimedWait(ten_seconds); |
- if (TimeTicks::Now() - start > ten_seconds) |
- break; |
- } |
- EXPECT_FALSE(syncer_thread()->vault_.connected_); |
- } |
- |
- bool Pause(ListenerMock* listener) { |
- WaitableEvent event(false, false); |
- { |
- base::AutoLock lock(syncer_thread()->lock_); |
- EXPECT_CALL(*listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_PAUSED))). |
- WillOnce(SignalEvent(&event)); |
- } |
- if (!syncer_thread()->RequestPause()) |
- return false; |
- return event.TimedWait(max_wait_time_); |
- } |
- |
- bool Resume(ListenerMock* listener) { |
- WaitableEvent event(false, false); |
- { |
- base::AutoLock lock(syncer_thread()->lock_); |
- EXPECT_CALL(*listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_RESUMED))). |
- WillOnce(SignalEvent(&event)); |
- } |
- if (!syncer_thread()->RequestResume()) |
- return false; |
- return event.TimedWait(max_wait_time_); |
- } |
- |
- void PreventThreadFromPolling() { |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
- } |
- |
- // Compare a provided TypePayloadMap to the pending nudge info stored in the |
- // SyncerThread vault. |
- bool CompareNudgeTypesToVault(const syncable::ModelTypePayloadMap& lhs) { |
- const syncable::ModelTypePayloadMap& vault_nudge_types = |
- syncer_thread()->vault_.pending_nudge_types_; |
- return lhs == vault_nudge_types; |
- } |
- |
- // Compare a provided ModelTypeBitset to the pending nudge info stored in the |
- // SyncerThread vault. Nudge info in vault must not have any non-empty |
- // payloads. |
- bool CompareNudgeTypesBitSetToVault(const syncable::ModelTypeBitSet& lhs) { |
- syncable::ModelTypePayloadMap model_types_with_payloads = |
- syncable::ModelTypePayloadMapFromBitSet(lhs, std::string()); |
- size_t count = 0; |
- for (syncable::ModelTypePayloadMap::const_iterator i = |
- syncer_thread()->vault_.pending_nudge_types_.begin(); |
- i != syncer_thread()->vault_.pending_nudge_types_.end(); |
- ++i, ++count) { |
- if (!lhs.test(i->first)) |
- return false; |
- } |
- if (lhs.count() != count) |
- return false; |
- return true; |
- } |
- |
- |
- private: |
- |
- virtual void OnSyncEngineEvent(const SyncEngineEvent& event) { |
- if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) |
- sync_cycle_ended_event_.Signal(); |
- } |
- |
- protected: |
- TimeDelta max_wait_time_; |
- SyncSessionContext* context_; |
- |
- private: |
- ManuallyOpenedTestDirectorySetterUpper metadb_; |
- scoped_ptr<MockConnectionManager> connection_; |
- scoped_refptr<SyncerThread> syncer_thread_; |
- scoped_refptr<ModelSafeWorker> worker_; |
- base::WaitableEvent sync_cycle_ended_event_; |
- DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest); |
-}; |
- |
-class SyncShareIntercept |
- : public MockConnectionManager::ResponseCodeOverrideRequestor, |
- public MockConnectionManager::MidCommitObserver { |
- public: |
- SyncShareIntercept() : sync_occured_(false, false), |
- allow_multiple_interceptions_(true) {} |
- virtual ~SyncShareIntercept() {} |
- virtual void Observe() { |
- if (!allow_multiple_interceptions_ && !times_sync_occured_.empty()) |
- FAIL() << "Multiple sync shares occured."; |
- times_sync_occured_.push_back(TimeTicks::Now()); |
- sync_occured_.Signal(); |
- } |
- |
- // ResponseCodeOverrideRequestor implementation. This assumes any override |
- // requested is intended to silence the SyncerThread. |
- virtual void OnOverrideComplete() { |
- // We should not see any syncing. |
- allow_multiple_interceptions_ = false; |
- times_sync_occured_.clear(); |
- } |
- |
- void WaitForSyncShare(int at_least_this_many, TimeDelta max_wait) { |
- while (at_least_this_many-- > 0) |
- sync_occured_.TimedWait(max_wait); |
- } |
- std::vector<TimeTicks> times_sync_occured() const { |
- return times_sync_occured_; |
- } |
- |
- void Reset() { |
- allow_multiple_interceptions_ = true; |
- times_sync_occured_.clear(); |
- sync_occured_.Reset(); |
- } |
- private: |
- std::vector<TimeTicks> times_sync_occured_; |
- base::WaitableEvent sync_occured_; |
- bool allow_multiple_interceptions_; |
- DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept); |
-}; |
- |
-TEST_F(SyncerThreadTest, Construction) { |
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, |
- std::vector<SyncEngineEventListener*>()); |
- scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context)); |
-} |
- |
-TEST_F(SyncerThreadTest, StartStop) { |
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, |
- std::vector<SyncEngineEventListener*>()); |
- scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context)); |
- EXPECT_TRUE(syncer_thread->Start()); |
- EXPECT_TRUE(syncer_thread->Stop(2000)); |
- |
- // Do it again for good measure. I caught some bugs by adding this so |
- // I would recommend keeping it. |
- EXPECT_TRUE(syncer_thread->Start()); |
- EXPECT_TRUE(syncer_thread->Stop(2000)); |
-} |
- |
-TEST(SyncerThread, GetRecommendedDelay) { |
- EXPECT_LE(0, SyncerThread::GetRecommendedDelaySeconds(0)); |
- EXPECT_LE(1, SyncerThread::GetRecommendedDelaySeconds(1)); |
- EXPECT_LE(50, SyncerThread::GetRecommendedDelaySeconds(50)); |
- EXPECT_LE(10, SyncerThread::GetRecommendedDelaySeconds(10)); |
- EXPECT_EQ(SyncerThread::kMaxBackoffSeconds, |
- SyncerThread::GetRecommendedDelaySeconds( |
- SyncerThread::kMaxBackoffSeconds)); |
- EXPECT_EQ(SyncerThread::kMaxBackoffSeconds, |
- SyncerThread::GetRecommendedDelaySeconds( |
- SyncerThread::kMaxBackoffSeconds+1)); |
-} |
- |
-TEST_F(SyncerThreadTest, CalculateSyncWaitTime) { |
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, |
- std::vector<SyncEngineEventListener*>()); |
- scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context)); |
- syncer_thread->DisableIdleDetection(); |
- |
- // Syncer_polling_interval_ is less than max poll interval. |
- TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1); |
- |
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); |
- |
- // user_idle_ms is less than 10 * (syncer_polling_interval*1000). |
- ASSERT_EQ(syncer_polling_interval.InMilliseconds(), |
- syncer_thread->CalculateSyncWaitTime(1000, 0)); |
- ASSERT_EQ(syncer_polling_interval.InMilliseconds(), |
- syncer_thread->CalculateSyncWaitTime(1000, 1)); |
- |
- // user_idle_ms is ge than 10 * (syncer_polling_interval*1000). |
- int last_poll_time = 2000; |
- ASSERT_TRUE(last_poll_time <= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000)); |
- ASSERT_TRUE(last_poll_time * 3 >= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000)); |
- ASSERT_TRUE(last_poll_time <= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000)); |
- ASSERT_TRUE(last_poll_time * 3 >= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000)); |
- |
- // Maximum backoff time should be syncer_max_interval. |
- int near_threshold = SyncerThread::kDefaultMaxPollIntervalMs / 2 - 1; |
- int threshold = SyncerThread::kDefaultMaxPollIntervalMs; |
- int over_threshold = SyncerThread::kDefaultMaxPollIntervalMs + 1; |
- ASSERT_TRUE(near_threshold <= |
- syncer_thread->CalculateSyncWaitTime(near_threshold, 10000)); |
- ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs >= |
- syncer_thread->CalculateSyncWaitTime(near_threshold, 10000)); |
- ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs == |
- syncer_thread->CalculateSyncWaitTime(threshold, 10000)); |
- ASSERT_TRUE(SyncerThread::kDefaultMaxPollIntervalMs == |
- syncer_thread->CalculateSyncWaitTime(over_threshold, 10000)); |
- |
- // Possible idle time must be capped by syncer_max_interval. |
- int over_sync_max_interval = |
- SyncerThread::kDefaultMaxPollIntervalMs + 1; |
- syncer_polling_interval = TimeDelta::FromSeconds( |
- over_sync_max_interval / 100); // so 1000* is right |
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); |
- ASSERT_EQ(syncer_polling_interval.InSeconds() * 1000, |
- syncer_thread->CalculateSyncWaitTime(1000, over_sync_max_interval)); |
- syncer_polling_interval = TimeDelta::FromSeconds(1); |
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); |
- ASSERT_TRUE(last_poll_time <= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, |
- over_sync_max_interval)); |
- ASSERT_TRUE(last_poll_time * 3 >= |
- syncer_thread->CalculateSyncWaitTime(last_poll_time, |
- over_sync_max_interval)); |
-} |
- |
-TEST_F(SyncerThreadTest, CalculatePollingWaitTime) { |
- // Set up the environment. |
- int user_idle_milliseconds_param = 0; |
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, |
- std::vector<SyncEngineEventListener*>()); |
- scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context)); |
- syncer_thread->DisableIdleDetection(); |
- // Hold the lock to appease asserts in code. |
- base::AutoLock lock(syncer_thread->lock_); |
- |
- // Notifications disabled should result in a polling interval of |
- // kDefaultShortPollInterval. |
- { |
- context->set_notifications_enabled(false); |
- bool continue_sync_cycle_param = false; |
- |
- // No work and no backoff. |
- WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- |
- // In this case the continue_sync_cycle is turned off. |
- continue_sync_cycle_param = true; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- } |
- |
- // Notifications enabled should result in a polling interval of |
- // SyncerThread::kDefaultLongPollIntervalSeconds. |
- { |
- context->set_notifications_enabled(true); |
- bool continue_sync_cycle_param = false; |
- |
- // No work and no backoff. |
- WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- |
- // In this case the continue_sync_cycle is turned off. |
- continue_sync_cycle_param = true; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- } |
- |
- // There are two states which can cause a continuation, either the updates |
- // available do not match the updates received, or the unsynced count is |
- // non-zero. |
- { |
- // More server changes remaining to download. |
- context->set_last_snapshot(SessionSnapshotForTest(1, 0)); |
- bool continue_sync_cycle_param = false; |
- |
- WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_LE(0, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- continue_sync_cycle_param = false; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(3, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_LE(0, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(2, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // Now simulate no more server changes remaining. |
- context->set_last_snapshot(SessionSnapshotForTest(0, 0)); |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- } |
- |
- { |
- // Now try with unsynced local items. |
- context->set_last_snapshot(SessionSnapshotForTest(0, 1)); |
- bool continue_sync_cycle_param = false; |
- |
- WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_LE(0, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- continue_sync_cycle_param = false; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 0, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(2, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- context->set_last_snapshot(SessionSnapshotForTest(0, 0)); |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 4, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- } |
- |
- // Regression for exponential backoff reset when the syncer is nudged. |
- { |
- context->set_last_snapshot(SessionSnapshotForTest(0, 1)); |
- bool continue_sync_cycle_param = false; |
- |
- // Expect move from default polling interval to exponential backoff due to |
- // unsynced_count != 0. |
- WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
- 3600, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_LE(0, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- continue_sync_cycle_param = false; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 3600, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(2, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // Expect exponential backoff. |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 2, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_LE(2, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 2, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(6, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- syncer_thread->vault_.current_wait_interval_ = interval; |
- |
- interval = syncer_thread->CalculatePollingWaitTime( |
- static_cast<int>(interval.poll_delta.InSeconds()), |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- true); |
- |
- // Don't change poll on a failed nudge during backoff. |
- ASSERT_TRUE(syncer_thread->vault_.current_wait_interval_.poll_delta == |
- interval.poll_delta); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_TRUE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // If we got a nudge and we weren't in backoff mode, we see exponential |
- // backoff. |
- syncer_thread->vault_.current_wait_interval_.mode = WaitInterval::NORMAL; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 2, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- true); |
- |
- // 5 and 3 are bounds on the backoff randomization formula given input of 2. |
- ASSERT_GE(5, interval.poll_delta.InSeconds()); |
- ASSERT_LE(3, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // And if another interval expires, we get a bigger backoff. |
- WaitInterval new_interval = syncer_thread->CalculatePollingWaitTime( |
- static_cast<int>(interval.poll_delta.InSeconds()), |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- false); |
- |
- ASSERT_GE(12, new_interval.poll_delta.InSeconds()); |
- ASSERT_LE(5, new_interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::EXPONENTIAL_BACKOFF, interval.mode); |
- ASSERT_FALSE(new_interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // A nudge resets the continue_sync_cycle_param value, so our backoff |
- // should return to the minimum. |
- continue_sync_cycle_param = false; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 3600, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- true); |
- |
- ASSERT_LE(0, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- continue_sync_cycle_param = false; |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 3600, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- true); |
- |
- ASSERT_GE(2, interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_TRUE(continue_sync_cycle_param); |
- |
- // Setting unsynced_count = 0 returns us to the default polling interval. |
- context->set_last_snapshot(SessionSnapshotForTest(0, 0)); |
- interval = syncer_thread->CalculatePollingWaitTime( |
- 4, |
- &user_idle_milliseconds_param, |
- &continue_sync_cycle_param, |
- true); |
- |
- ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
- interval.poll_delta.InSeconds()); |
- ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
- ASSERT_FALSE(interval.had_nudge_during_backoff); |
- ASSERT_FALSE(continue_sync_cycle_param); |
- } |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, Polling) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- |
- const TimeDelta poll_interval = TimeDelta::FromSeconds(1); |
- syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- |
- TimeDelta two_polls = poll_interval + poll_interval; |
- // We could theoretically return immediately from the wait if the interceptor |
- // was already signaled for a SyncShare (the first one comes quick). |
- interceptor.WaitForSyncShare(1, two_polls); |
- EXPECT_FALSE(interceptor.times_sync_occured().empty()); |
- |
- // Wait for at least 2 more SyncShare operations. |
- interceptor.WaitForSyncShare(2, two_polls); |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
- |
- // Now analyze the run. |
- std::vector<TimeTicks> data = interceptor.times_sync_occured(); |
- |
- EXPECT_GE(data.size(), static_cast<unsigned int>(3)); |
- for (unsigned int i = 0; i < data.size() - 1; i++) { |
- TimeTicks optimal_next_sync = data[i] + poll_interval; |
- EXPECT_TRUE(data[i + 1] >= optimal_next_sync); |
- // This should be reliable, as there are no blocking or I/O operations |
- // except the explicit 2 second wait, so if it takes longer than this |
- // there is a problem. |
- EXPECT_TRUE(data[i + 1] < optimal_next_sync + poll_interval); |
- } |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, Nudge) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- // We don't want a poll to happen during this test (except the first one). |
- PreventThreadFromPolling(); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
- |
- EXPECT_EQ(static_cast<unsigned int>(1), |
- interceptor.times_sync_occured().size()); |
- // The SyncerThread should be waiting for the poll now. Nudge it to sync |
- // immediately (5ms). |
- syncer_thread()->NudgeSyncer(5, SyncerThread::kUnknown); |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(static_cast<unsigned int>(2), |
- interceptor.times_sync_occured().size()); |
- |
- // SyncerThread should be waiting again. Signal it to stop. |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypes) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- // We don't want a poll to happen during this test (except the first one). |
- PreventThreadFromPolling(); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
- EXPECT_EQ(static_cast<unsigned int>(1), |
- interceptor.times_sync_occured().size()); |
- |
- // The SyncerThread should be waiting for the poll now. Nudge it to sync |
- // immediately (5ms). |
- syncable::ModelTypeBitSet model_types; |
- model_types[syncable::BOOKMARKS] = true; |
- |
- // Paused so we can verify the nudge types safely. |
- syncer_thread()->RequestPause(); |
- syncer_thread()->NudgeSyncerWithDataTypes(5, |
- SyncerThread::kUnknown, |
- model_types); |
- EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
- syncer_thread()->RequestResume(); |
- |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(static_cast<unsigned int>(2), |
- interceptor.times_sync_occured().size()); |
- |
- // SyncerThread should be waiting again. Signal it to stop. |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
- EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypesCoalesced) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- // We don't want a poll to happen during this test (except the first one). |
- PreventThreadFromPolling(); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
- EXPECT_EQ(static_cast<unsigned int>(1), |
- interceptor.times_sync_occured().size()); |
- |
- // The SyncerThread should be waiting for the poll now. Nudge it to sync |
- // immediately (5ms). |
- syncable::ModelTypeBitSet model_types; |
- model_types[syncable::BOOKMARKS] = true; |
- |
- // Paused so we can verify the nudge types safely. |
- syncer_thread()->RequestPause(); |
- syncer_thread()->NudgeSyncerWithDataTypes(100, |
- SyncerThread::kUnknown, |
- model_types); |
- EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
- |
- model_types[syncable::BOOKMARKS] = false; |
- model_types[syncable::AUTOFILL] = true; |
- syncer_thread()->NudgeSyncerWithDataTypes(0, |
- SyncerThread::kUnknown, |
- model_types); |
- |
- // Reset BOOKMARKS for expectations. |
- model_types[syncable::BOOKMARKS] = true; |
- EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
- |
- syncer_thread()->RequestResume(); |
- |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(static_cast<unsigned int>(2), |
- interceptor.times_sync_occured().size()); |
- |
- // SyncerThread should be waiting again. Signal it to stop. |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
- EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloads) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- // We don't want a poll to happen during this test (except the first one). |
- PreventThreadFromPolling(); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
- EXPECT_EQ(static_cast<unsigned int>(1), |
- interceptor.times_sync_occured().size()); |
- |
- // The SyncerThread should be waiting for the poll now. Nudge it to sync |
- // immediately (5ms). |
- syncable::ModelTypePayloadMap nudge_types; |
- nudge_types[syncable::BOOKMARKS] = "test"; |
- connection()->ExpectGetUpdatesRequestPayloads(nudge_types); |
- |
- // Paused so we can verify the nudge types safely. |
- syncer_thread()->RequestPause(); |
- syncer_thread()->NudgeSyncerWithPayloads(5, |
- SyncerThread::kUnknown, |
- nudge_types); |
- EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); |
- syncer_thread()->RequestResume(); |
- |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(static_cast<unsigned int>(2), |
- interceptor.times_sync_occured().size()); |
- |
- // SyncerThread should be waiting again. Signal it to stop. |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
- EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloadsCoalesced) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- // We don't want a poll to happen during this test (except the first one). |
- PreventThreadFromPolling(); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
- EXPECT_EQ(static_cast<unsigned int>(1), |
- interceptor.times_sync_occured().size()); |
- |
- // The SyncerThread should be waiting for the poll now. Nudge it to sync |
- // immediately (5ms). |
- syncable::ModelTypePayloadMap nudge_types; |
- nudge_types[syncable::BOOKMARKS] = "books"; |
- |
- // Paused so we can verify the nudge types safely. |
- syncer_thread()->RequestPause(); |
- syncer_thread()->NudgeSyncerWithPayloads(100, |
- SyncerThread::kUnknown, |
- nudge_types); |
- EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); |
- |
- nudge_types.erase(syncable::BOOKMARKS); |
- nudge_types[syncable::AUTOFILL] = "auto"; |
- syncer_thread()->NudgeSyncerWithPayloads(0, |
- SyncerThread::kUnknown, |
- nudge_types); |
- |
- // Reset BOOKMARKS for expectations. |
- nudge_types[syncable::BOOKMARKS] = "books"; |
- EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); |
- connection()->ExpectGetUpdatesRequestPayloads(nudge_types); |
- |
- syncer_thread()->RequestResume(); |
- |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(static_cast<unsigned int>(2), |
- interceptor.times_sync_occured().size()); |
- |
- // SyncerThread should be waiting again. Signal it to stop. |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
- EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, Throttling) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10); |
- syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
- |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- |
- // Wait for some healthy syncing. |
- interceptor.WaitForSyncShare(4, poll_interval + poll_interval); |
- |
- // Tell the server to throttle a single request, which should be all it takes |
- // to silence our syncer (for 2 hours, so we shouldn't hit that in this test). |
- // This will atomically visit the interceptor so it can switch to throttled |
- // mode and fail on multiple requests. |
- connection()->ThrottleNextRequest(&interceptor); |
- |
- // Try to trigger a sync (we have a really short poll interval already). |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- |
- // Wait until the syncer thread reports that it is throttled. Any further |
- // sync share interceptions will result in failure. If things are broken, |
- // we may never halt. |
- ASSERT_TRUE(WaitForThrottle()); |
- EXPECT_TRUE(syncer_thread()->IsSyncingCurrentlySilenced()); |
- |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, StopSyncPermanently) { |
- // The SyncerThread should request an exit from the Syncer and set |
- // conditions for termination. |
- const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10); |
- syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
- |
- ListenerMock listener; |
- WaitableEvent sync_cycle_ended_event(false, false); |
- WaitableEvent syncer_thread_exiting_event(false, false); |
- TestScopedSessionEventListener reg(context_, &listener); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STATUS_CHANGED))). |
- Times(AnyNumber()); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- Times(AnyNumber()). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STOP_SYNCING_PERMANENTLY))); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_EXITING))). |
- WillOnce(SignalEvent(&syncer_thread_exiting_event)); |
- |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- connection()->set_store_birthday("NotYourLuckyDay"); |
- ASSERT_TRUE(syncer_thread_exiting_event.TimedWait(max_wait_time_)); |
- EXPECT_TRUE(syncer_thread()->Stop(0)); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, AuthInvalid) { |
- SyncShareIntercept interceptor; |
- connection()->SetMidCommitObserver(&interceptor); |
- const TimeDelta poll_interval = TimeDelta::FromMilliseconds(1); |
- |
- syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
- EXPECT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- |
- // Wait for some healthy syncing. |
- interceptor.WaitForSyncShare(2, TimeDelta::FromSeconds(10)); |
- EXPECT_GE(interceptor.times_sync_occured().size(), 2U); |
- |
- // Atomically start returning auth invalid and set the interceptor to fail |
- // on any sync. |
- connection()->FailWithAuthInvalid(&interceptor); |
- WaitForDisconnect(); |
- |
- // Try to trigger a sync (the interceptor will assert if one occurs). |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- |
- // Wait several poll intervals but don't expect any syncing besides the cycle |
- // that lost the connection. |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
- EXPECT_EQ(1U, interceptor.times_sync_occured().size()); |
- |
- // Simulate a valid re-authentication and expect resumption of syncing. |
- interceptor.Reset(); |
- ASSERT_TRUE(interceptor.times_sync_occured().empty()); |
- connection()->StopFailingWithAuthInvalid(NULL); |
- ServerConnectionEvent e = {ServerConnectionEvent::STATUS_CHANGED, |
- HttpResponse::SERVER_CONNECTION_OK, |
- true}; |
- connection()->channel()->NotifyListeners(e); |
- |
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(10)); |
- EXPECT_FALSE(interceptor.times_sync_occured().empty()); |
- |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-// TODO(zea): Disabled, along with PauseWhenNotConnected, due to stalling on |
-// windows, preventing further sync unit tests from running. See crbug/39070. |
-TEST_F(SyncerThreadWithSyncerTest, DISABLED_Pause) { |
- WaitableEvent sync_cycle_ended_event(false, false); |
- WaitableEvent paused_event(false, false); |
- WaitableEvent resumed_event(false, false); |
- PreventThreadFromPolling(); |
- |
- ListenerMock listener; |
- TestScopedSessionEventListener reg(context_, &listener); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STATUS_CHANGED))). |
- Times(AnyNumber()); |
- |
- // Wait for the initial sync to complete. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_EXITING))); |
- |
- ASSERT_TRUE(syncer_thread()->Start()); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- // Request a pause. |
- ASSERT_TRUE(Pause(&listener)); |
- |
- // Resuming the pause. |
- ASSERT_TRUE(Resume(&listener)); |
- |
- // Not paused, should fail. |
- EXPECT_FALSE(syncer_thread()->RequestResume()); |
- |
- // Request a pause. |
- ASSERT_TRUE(Pause(&listener)); |
- |
- // Nudge the syncer, this should do nothing while we are paused. |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- |
- // Resuming will cause the nudge to be processed and a sync cycle to run. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- ASSERT_TRUE(Resume(&listener)); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, StartWhenNotConnected) { |
- WaitableEvent sync_cycle_ended_event(false, false); |
- WaitableEvent event(false, false); |
- ListenerMock listener; |
- TestScopedSessionEventListener reg(context_, &listener); |
- PreventThreadFromPolling(); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STATUS_CHANGED))). |
- Times(AnyNumber()); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_EXITING))); |
- |
- connection()->SetServerNotReachable(); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- |
- // Syncer thread will always go through once cycle at the start, |
- // then it will wait for a connection. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))). |
- WillOnce(SignalEvent(&event)); |
- ASSERT_TRUE(syncer_thread()->Start()); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- |
- // Connect, will put the syncer thread into its usually poll wait. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_CONNECTED))). |
- WillOnce(SignalEvent(&event)); |
- connection()->SetServerReachable(); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- |
- // Nudge the syncer to complete a cycle. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-// See TODO comment on the "Pause" test above. |
-TEST_F(SyncerThreadWithSyncerTest, DISABLED_PauseWhenNotConnected) { |
- WaitableEvent sync_cycle_ended_event(false, false); |
- WaitableEvent event(false, false); |
- ListenerMock listener; |
- TestScopedSessionEventListener reg(context_, &listener); |
- PreventThreadFromPolling(); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STATUS_CHANGED))). |
- Times(AnyNumber()); |
- |
- // Put the thread into a "waiting for connection" state. |
- connection()->SetServerNotReachable(); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))). |
- WillOnce(SignalEvent(&event)); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- |
- ASSERT_TRUE(syncer_thread()->Start()); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- |
- // Pause and resume the thread while waiting for a connection. |
- ASSERT_TRUE(Pause(&listener)); |
- ASSERT_TRUE(Resume(&listener)); |
- |
- // Make a connection and let the syncer cycle. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_CONNECTED))). |
- WillOnce(SignalEvent(&event)); |
- connection()->SetServerReachable(); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- // Disconnect and get into the waiting for a connection state. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_WAITING_FOR_CONNECTION))). |
- WillOnce(SignalEvent(&event)); |
- connection()->SetServerNotReachable(); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- |
- // Pause so we can test getting a connection while paused. |
- ASSERT_TRUE(Pause(&listener)); |
- |
- // Get a connection then resume. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_CONNECTED))). |
- WillOnce(SignalEvent(&event)); |
- connection()->SetServerReachable(); |
- ASSERT_TRUE(event.TimedWait(max_wait_time_)); |
- |
- ASSERT_TRUE(Resume(&listener)); |
- |
- // Cycle the syncer to show we are not longer paused. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_EXITING))); |
- |
- syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-TEST_F(SyncerThreadWithSyncerTest, PauseResumeWhenNotRunning) { |
- WaitableEvent sync_cycle_ended_event(false, false); |
- WaitableEvent event(false, false); |
- ListenerMock listener; |
- TestScopedSessionEventListener reg(context_, &listener); |
- PreventThreadFromPolling(); |
- |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::STATUS_CHANGED))). |
- Times(AnyNumber()); |
- |
- // Pause and resume the syncer while not running |
- ASSERT_TRUE(Pause(&listener)); |
- ASSERT_TRUE(Resume(&listener)); |
- |
- // Pause the thread then start the syncer. |
- ASSERT_TRUE(Pause(&listener)); |
- metadb()->Open(); |
- syncer_thread()->CreateSyncer(metadb()->name()); |
- ASSERT_TRUE(syncer_thread()->Start()); |
- |
- // Resume and let the syncer cycle. |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNC_CYCLE_ENDED))). |
- WillOnce(SignalEvent(&sync_cycle_ended_event)); |
- EXPECT_CALL(listener, OnSyncEngineEvent( |
- Field(&SyncEngineEvent::what_happened, |
- SyncEngineEvent::SYNCER_THREAD_EXITING))); |
- |
- ASSERT_TRUE(Resume(&listener)); |
- ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
- EXPECT_TRUE(syncer_thread()->Stop(2000)); |
-} |
- |
-} // namespace browser_sync |