| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <list> | 5 #include <list> |
| 6 #include <map> | 6 #include <map> |
| 7 #include <set> | 7 #include <set> |
| 8 #include <strstream> | 8 #include <strstream> |
| 9 | 9 |
| 10 #include "base/command_line.h" | |
| 11 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
| 12 #include "base/time.h" | |
| 13 #include "chrome/browser/sync/engine/model_safe_worker.h" | |
| 14 #include "chrome/browser/sync/engine/syncer_thread.h" | 11 #include "chrome/browser/sync/engine/syncer_thread.h" |
| 15 #include "chrome/browser/sync/engine/syncer_thread_timed_stop.h" | |
| 16 #include "chrome/test/sync/engine/mock_server_connection.h" | |
| 17 #include "chrome/test/sync/engine/test_directory_setter_upper.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 13 |
| 20 using base::Time; | |
| 21 using base::TimeDelta; | |
| 22 | |
| 23 namespace browser_sync { | 14 namespace browser_sync { |
| 24 | 15 |
| 25 typedef testing::Test SyncerThreadTest; | 16 class SyncerThreadTest : public testing::Test { |
| 17 protected: |
| 18 SyncerThreadTest() {} |
| 19 virtual ~SyncerThreadTest() {} |
| 20 virtual void SetUp() {} |
| 21 virtual void TearDown() {} |
| 26 | 22 |
| 27 class SyncerThreadWithSyncerTest : public testing::Test { | |
| 28 public: | |
| 29 SyncerThreadWithSyncerTest() {} | |
| 30 virtual void SetUp() { | |
| 31 metadb_.SetUp(); | |
| 32 connection_.reset(new MockConnectionManager(metadb_.manager(), | |
| 33 metadb_.name())); | |
| 34 allstatus_.reset(new AllStatus()); | |
| 35 | |
| 36 syncer_thread_ = SyncerThreadFactory::Create(NULL, metadb_.manager(), | |
| 37 connection_.get(), allstatus_.get(), new ModelSafeWorker()); | |
| 38 | |
| 39 allstatus_->WatchSyncerThread(syncer_thread_); | |
| 40 syncer_thread_->SetConnected(true); | |
| 41 } | |
| 42 virtual void TearDown() { | |
| 43 syncer_thread_ = NULL; | |
| 44 allstatus_.reset(); | |
| 45 connection_.reset(); | |
| 46 metadb_.TearDown(); | |
| 47 } | |
| 48 | |
| 49 ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; } | |
| 50 MockConnectionManager* connection() { return connection_.get(); } | |
| 51 SyncerThread* syncer_thread() { return syncer_thread_; } | |
| 52 private: | 23 private: |
| 53 ManuallyOpenedTestDirectorySetterUpper metadb_; | 24 DISALLOW_COPY_AND_ASSIGN(SyncerThreadTest); |
| 54 scoped_ptr<MockConnectionManager> connection_; | |
| 55 scoped_ptr<AllStatus> allstatus_; | |
| 56 scoped_refptr<SyncerThread> syncer_thread_; | |
| 57 DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest); | |
| 58 }; | |
| 59 | |
| 60 class SyncShareIntercept : public MockConnectionManager::MidCommitObserver { | |
| 61 public: | |
| 62 SyncShareIntercept() : sync_occured_(false, false) {} | |
| 63 virtual ~SyncShareIntercept() {} | |
| 64 virtual void Observe() { | |
| 65 times_sync_occured_.push_back(Time::NowFromSystemTime()); | |
| 66 sync_occured_.Signal(); | |
| 67 } | |
| 68 void WaitForSyncShare(int at_least_this_many, TimeDelta max_wait) { | |
| 69 while (at_least_this_many-- > 0) | |
| 70 sync_occured_.TimedWait(max_wait); | |
| 71 } | |
| 72 std::vector<Time> times_sync_occured() const { | |
| 73 return times_sync_occured_; | |
| 74 } | |
| 75 private: | |
| 76 std::vector<Time> times_sync_occured_; | |
| 77 base::WaitableEvent sync_occured_; | |
| 78 DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept); | |
| 79 }; | 25 }; |
| 80 | 26 |
| 81 TEST_F(SyncerThreadTest, Construction) { | 27 TEST_F(SyncerThreadTest, Construction) { |
| 82 scoped_refptr<SyncerThread> syncer_thread( | 28 SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL); |
| 83 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | |
| 84 } | |
| 85 | |
| 86 TEST_F(SyncerThreadTest, StartStop) { | |
| 87 scoped_refptr<SyncerThread> syncer_thread( | |
| 88 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | |
| 89 EXPECT_TRUE(syncer_thread->Start()); | |
| 90 EXPECT_TRUE(syncer_thread->Stop(2000)); | |
| 91 | |
| 92 // Do it again for good measure. I caught some bugs by adding this so | |
| 93 // I would recommend keeping it. | |
| 94 EXPECT_TRUE(syncer_thread->Start()); | |
| 95 EXPECT_TRUE(syncer_thread->Stop(2000)); | |
| 96 } | 29 } |
| 97 | 30 |
| 98 TEST_F(SyncerThreadTest, CalculateSyncWaitTime) { | 31 TEST_F(SyncerThreadTest, CalculateSyncWaitTime) { |
| 99 scoped_refptr<SyncerThread> syncer_thread( | 32 SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL); |
| 100 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 33 syncer_thread.DisableIdleDetection(); |
| 101 syncer_thread->DisableIdleDetection(); | |
| 102 | 34 |
| 103 // Syncer_polling_interval_ is less than max poll interval. | 35 // Syncer_polling_interval_ is less than max poll interval |
| 104 TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1); | 36 int syncer_polling_interval = 1; // Needed since AssertionResult is not a |
| 105 | 37 // friend of SyncerThread |
| 106 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); | 38 syncer_thread.syncer_polling_interval_ = syncer_polling_interval; |
| 107 | 39 |
| 108 // user_idle_ms is less than 10 * (syncer_polling_interval*1000). | 40 // user_idle_ms is less than 10 * (syncer_polling_interval*1000). |
| 109 ASSERT_EQ(syncer_polling_interval.InMilliseconds(), | 41 ASSERT_EQ(syncer_polling_interval * 1000, |
| 110 syncer_thread->CalculateSyncWaitTime(1000, 0)); | 42 syncer_thread.CalculateSyncWaitTime(1000, 0)); |
| 111 ASSERT_EQ(syncer_polling_interval.InMilliseconds(), | 43 ASSERT_EQ(syncer_polling_interval * 1000, |
| 112 syncer_thread->CalculateSyncWaitTime(1000, 1)); | 44 syncer_thread.CalculateSyncWaitTime(1000, 1)); |
| 113 | 45 |
| 114 // user_idle_ms is ge than 10 * (syncer_polling_interval*1000). | 46 // user_idle_ms is ge than 10 * (syncer_polling_interval*1000). |
| 115 int last_poll_time = 2000; | 47 int last_poll_time = 2000; |
| 116 ASSERT_LE(last_poll_time, | 48 ASSERT_LE(last_poll_time, |
| 117 syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000)); | 49 syncer_thread.CalculateSyncWaitTime(last_poll_time, 10000)); |
| 118 ASSERT_GE(last_poll_time*3, | 50 ASSERT_GE(last_poll_time*3, |
| 119 syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000)); | 51 syncer_thread.CalculateSyncWaitTime(last_poll_time, 10000)); |
| 120 ASSERT_LE(last_poll_time, | 52 ASSERT_LE(last_poll_time, |
| 121 syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000)); | 53 syncer_thread.CalculateSyncWaitTime(last_poll_time, 100000)); |
| 122 ASSERT_GE(last_poll_time*3, | 54 ASSERT_GE(last_poll_time*3, |
| 123 syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000)); | 55 syncer_thread.CalculateSyncWaitTime(last_poll_time, 100000)); |
| 124 | 56 |
| 125 // Maximum backoff time should be syncer_max_interval. | 57 // Maximum backoff time should be syncer_max_interval. |
| 126 int near_threshold = SyncerThread::kDefaultMaxPollIntervalMs / 2 - 1; | 58 int near_threshold = SyncerThread::kDefaultMaxPollIntervalMs / 2 - 1; |
| 127 int threshold = SyncerThread::kDefaultMaxPollIntervalMs; | 59 int threshold = SyncerThread::kDefaultMaxPollIntervalMs; |
| 128 int over_threshold = SyncerThread::kDefaultMaxPollIntervalMs + 1; | 60 int over_threshold = SyncerThread::kDefaultMaxPollIntervalMs + 1; |
| 129 ASSERT_LE(near_threshold, | 61 ASSERT_LE(near_threshold, |
| 130 syncer_thread->CalculateSyncWaitTime(near_threshold, 10000)); | 62 syncer_thread.CalculateSyncWaitTime(near_threshold, 10000)); |
| 131 ASSERT_GE(SyncerThread::kDefaultMaxPollIntervalMs, | 63 ASSERT_GE(SyncerThread::kDefaultMaxPollIntervalMs, |
| 132 syncer_thread->CalculateSyncWaitTime(near_threshold, 10000)); | 64 syncer_thread.CalculateSyncWaitTime(near_threshold, 10000)); |
| 133 ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs, | 65 ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs, |
| 134 syncer_thread->CalculateSyncWaitTime(threshold, 10000)); | 66 syncer_thread.CalculateSyncWaitTime(threshold, 10000)); |
| 135 ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs, | 67 ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs, |
| 136 syncer_thread->CalculateSyncWaitTime(over_threshold, 10000)); | 68 syncer_thread.CalculateSyncWaitTime(over_threshold, 10000)); |
| 137 | 69 |
| 138 // Possible idle time must be capped by syncer_max_interval. | 70 // Possible idle time must be capped by syncer_max_interval. |
| 139 int over_sync_max_interval = | 71 int over_sync_max_interval = |
| 140 SyncerThread::kDefaultMaxPollIntervalMs + 1; | 72 SyncerThread::kDefaultMaxPollIntervalMs + 1; |
| 141 syncer_polling_interval = TimeDelta::FromSeconds( | 73 syncer_polling_interval = over_sync_max_interval / 100; // so 1000* is right |
| 142 over_sync_max_interval / 100); // so 1000* is right | 74 syncer_thread.syncer_polling_interval_ = syncer_polling_interval; |
| 143 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); | 75 ASSERT_EQ(syncer_polling_interval * 1000, |
| 144 ASSERT_EQ(syncer_polling_interval.InSeconds() * 1000, | 76 syncer_thread.CalculateSyncWaitTime(1000, over_sync_max_interval)); |
| 145 syncer_thread->CalculateSyncWaitTime(1000, over_sync_max_interval)); | 77 syncer_polling_interval = 1; |
| 146 syncer_polling_interval = TimeDelta::FromSeconds(1); | 78 syncer_thread.syncer_polling_interval_ = syncer_polling_interval; |
| 147 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); | |
| 148 ASSERT_LE(last_poll_time, | 79 ASSERT_LE(last_poll_time, |
| 149 syncer_thread->CalculateSyncWaitTime(last_poll_time, | 80 syncer_thread.CalculateSyncWaitTime(last_poll_time, |
| 150 over_sync_max_interval)); | 81 over_sync_max_interval)); |
| 151 ASSERT_GE(last_poll_time * 3, | 82 ASSERT_GE(last_poll_time * 3, |
| 152 syncer_thread->CalculateSyncWaitTime(last_poll_time, | 83 syncer_thread.CalculateSyncWaitTime(last_poll_time, |
| 153 over_sync_max_interval)); | 84 over_sync_max_interval)); |
| 154 } | 85 } |
| 155 | 86 |
| 156 TEST_F(SyncerThreadTest, CalculatePollingWaitTime) { | 87 TEST_F(SyncerThreadTest, CalculatePollingWaitTime) { |
| 157 // Set up the environment. | 88 // Set up the environment. |
| 158 int user_idle_milliseconds_param = 0; | 89 int user_idle_milliseconds_param = 0; |
| 159 scoped_refptr<SyncerThread> syncer_thread( | 90 |
| 160 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 91 SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL); |
| 161 syncer_thread->DisableIdleDetection(); | 92 syncer_thread.DisableIdleDetection(); |
| 162 | 93 |
| 163 // Notifications disabled should result in a polling interval of | 94 // Notifications disabled should result in a polling interval of |
| 164 // kDefaultShortPollInterval. | 95 // kDefaultShortPollInterval. |
| 165 { | 96 { |
| 166 AllStatus::Status status = {}; | 97 AllStatus::Status status = {}; |
| 167 status.notifications_enabled = 0; | 98 status.notifications_enabled = 0; |
| 168 bool continue_sync_cycle_param = false; | 99 bool continue_sync_cycle_param = false; |
| 169 | 100 |
| 170 // No work and no backoff. | 101 // No work and no backoff. |
| 171 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, | 102 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
| 172 syncer_thread->CalculatePollingWaitTime( | 103 syncer_thread.CalculatePollingWaitTime( |
| 173 status, | 104 status, |
| 174 0, | 105 0, |
| 175 &user_idle_milliseconds_param, | 106 &user_idle_milliseconds_param, |
| 176 &continue_sync_cycle_param)); | 107 &continue_sync_cycle_param)); |
| 177 ASSERT_FALSE(continue_sync_cycle_param); | 108 ASSERT_FALSE(continue_sync_cycle_param); |
| 178 | 109 |
| 179 // In this case the continue_sync_cycle is turned off. | 110 // In this case the continue_sync_cycle is turned off. |
| 180 continue_sync_cycle_param = true; | 111 continue_sync_cycle_param = true; |
| 181 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, | 112 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
| 182 syncer_thread->CalculatePollingWaitTime( | 113 syncer_thread.CalculatePollingWaitTime( |
| 183 status, | 114 status, |
| 184 0, | 115 0, |
| 185 &user_idle_milliseconds_param, | 116 &user_idle_milliseconds_param, |
| 186 &continue_sync_cycle_param)); | 117 &continue_sync_cycle_param)); |
| 187 ASSERT_FALSE(continue_sync_cycle_param); | 118 ASSERT_FALSE(continue_sync_cycle_param); |
| 188 | 119 |
| 189 // TODO(brg) : Find a way to test exponential backoff is inoperable. | 120 // TODO(brg) : Find a way to test exponential backoff is inoperable. |
| 190 // Exponential backoff should be turned on when notifications are disabled | 121 // Exponential backoff should be turned on when notifications are disabled |
| 191 // but this can not be tested since we can not set the last input info. | 122 // but this can not be tested since we can not set the last input info. |
| 192 } | 123 } |
| 193 | 124 |
| 194 // Notifications enabled should result in a polling interval of | 125 // Notifications enabled should result in a polling interval of |
| 195 // SyncerThread::kDefaultLongPollIntervalSeconds. | 126 // SyncerThread::kDefaultLongPollIntervalSeconds. |
| 196 { | 127 { |
| 197 AllStatus::Status status = {}; | 128 AllStatus::Status status = {}; |
| 198 status.notifications_enabled = 1; | 129 status.notifications_enabled = 1; |
| 199 bool continue_sync_cycle_param = false; | 130 bool continue_sync_cycle_param = false; |
| 200 | 131 |
| 201 // No work and no backoff. | 132 // No work and no backoff. |
| 202 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, | 133 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
| 203 syncer_thread->CalculatePollingWaitTime( | 134 syncer_thread.CalculatePollingWaitTime( |
| 204 status, | 135 status, |
| 205 0, | 136 0, |
| 206 &user_idle_milliseconds_param, | 137 &user_idle_milliseconds_param, |
| 207 &continue_sync_cycle_param)); | 138 &continue_sync_cycle_param)); |
| 208 ASSERT_FALSE(continue_sync_cycle_param); | 139 ASSERT_FALSE(continue_sync_cycle_param); |
| 209 | 140 |
| 210 // In this case the continue_sync_cycle is turned off. | 141 // In this case the continue_sync_cycle is turned off. |
| 211 continue_sync_cycle_param = true; | 142 continue_sync_cycle_param = true; |
| 212 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, | 143 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
| 213 syncer_thread->CalculatePollingWaitTime( | 144 syncer_thread.CalculatePollingWaitTime( |
| 214 status, | 145 status, |
| 215 0, | 146 0, |
| 216 &user_idle_milliseconds_param, | 147 &user_idle_milliseconds_param, |
| 217 &continue_sync_cycle_param)); | 148 &continue_sync_cycle_param)); |
| 218 ASSERT_FALSE(continue_sync_cycle_param); | 149 ASSERT_FALSE(continue_sync_cycle_param); |
| 219 | 150 |
| 220 // TODO(brg) : Find a way to test exponential backoff. | 151 // TODO(brg) : Find a way to test exponential backoff. |
| 221 // Exponential backoff should be turned off when notifications are enabled, | 152 // Exponential backoff should be turned off when notifications are enabled, |
| 222 // but this can not be tested since we can not set the last input info. | 153 // but this can not be tested since we can not set the last input info. |
| 223 } | 154 } |
| 224 | 155 |
| 225 // There are two states which can cause a continuation, either the updates | 156 // There are two states which can cause a continuation, either the updates |
| 226 // available do not match the updates received, or the unsynced count is | 157 // available do not match the updates received, or the unsynced count is |
| 227 // non-zero. | 158 // non-zero. |
| 228 { | 159 { |
| 229 AllStatus::Status status = {}; | 160 AllStatus::Status status = {}; |
| 230 status.updates_available = 1; | 161 status.updates_available = 1; |
| 231 status.updates_received = 0; | 162 status.updates_received = 0; |
| 232 bool continue_sync_cycle_param = false; | 163 bool continue_sync_cycle_param = false; |
| 233 | 164 |
| 234 ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime( | 165 ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime( |
| 235 status, | 166 status, |
| 236 0, | 167 0, |
| 237 &user_idle_milliseconds_param, | 168 &user_idle_milliseconds_param, |
| 238 &continue_sync_cycle_param)); | 169 &continue_sync_cycle_param)); |
| 239 ASSERT_TRUE(continue_sync_cycle_param); | 170 ASSERT_TRUE(continue_sync_cycle_param); |
| 240 | 171 |
| 241 continue_sync_cycle_param = false; | 172 continue_sync_cycle_param = false; |
| 242 ASSERT_GE(3, syncer_thread->CalculatePollingWaitTime( | 173 ASSERT_GE(3, syncer_thread.CalculatePollingWaitTime( |
| 243 status, | 174 status, |
| 244 0, | 175 0, |
| 245 &user_idle_milliseconds_param, | 176 &user_idle_milliseconds_param, |
| 246 &continue_sync_cycle_param)); | 177 &continue_sync_cycle_param)); |
| 247 ASSERT_TRUE(continue_sync_cycle_param); | 178 ASSERT_TRUE(continue_sync_cycle_param); |
| 248 | 179 |
| 249 ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime( | 180 ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime( |
| 250 status, | 181 status, |
| 251 0, | 182 0, |
| 252 &user_idle_milliseconds_param, | 183 &user_idle_milliseconds_param, |
| 253 &continue_sync_cycle_param)); | 184 &continue_sync_cycle_param)); |
| 254 ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime( | 185 ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime( |
| 255 status, | 186 status, |
| 256 0, | 187 0, |
| 257 &user_idle_milliseconds_param, | 188 &user_idle_milliseconds_param, |
| 258 &continue_sync_cycle_param)); | 189 &continue_sync_cycle_param)); |
| 259 ASSERT_TRUE(continue_sync_cycle_param); | 190 ASSERT_TRUE(continue_sync_cycle_param); |
| 260 | 191 |
| 261 status.updates_received = 1; | 192 status.updates_received = 1; |
| 262 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, | 193 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
| 263 syncer_thread->CalculatePollingWaitTime( | 194 syncer_thread.CalculatePollingWaitTime( |
| 264 status, | 195 status, |
| 265 10, | 196 10, |
| 266 &user_idle_milliseconds_param, | 197 &user_idle_milliseconds_param, |
| 267 &continue_sync_cycle_param)); | 198 &continue_sync_cycle_param)); |
| 268 ASSERT_FALSE(continue_sync_cycle_param); | 199 ASSERT_FALSE(continue_sync_cycle_param); |
| 269 } | 200 } |
| 270 | 201 |
| 271 { | 202 { |
| 272 AllStatus::Status status = {}; | 203 AllStatus::Status status = {}; |
| 273 status.unsynced_count = 1; | 204 status.unsynced_count = 1; |
| 274 bool continue_sync_cycle_param = false; | 205 bool continue_sync_cycle_param = false; |
| 275 | 206 |
| 276 ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime( | 207 ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime( |
| 277 status, | 208 status, |
| 278 0, | 209 0, |
| 279 &user_idle_milliseconds_param, | 210 &user_idle_milliseconds_param, |
| 280 &continue_sync_cycle_param)); | 211 &continue_sync_cycle_param)); |
| 281 ASSERT_TRUE(continue_sync_cycle_param); | 212 ASSERT_TRUE(continue_sync_cycle_param); |
| 282 | 213 |
| 283 continue_sync_cycle_param = false; | 214 continue_sync_cycle_param = false; |
| 284 ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime( | 215 ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime( |
| 285 status, | 216 status, |
| 286 0, | 217 0, |
| 287 &user_idle_milliseconds_param, | 218 &user_idle_milliseconds_param, |
| 288 &continue_sync_cycle_param)); | 219 &continue_sync_cycle_param)); |
| 289 ASSERT_TRUE(continue_sync_cycle_param); | 220 ASSERT_TRUE(continue_sync_cycle_param); |
| 290 | 221 |
| 291 status.unsynced_count = 0; | 222 status.unsynced_count = 0; |
| 292 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, | 223 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
| 293 syncer_thread->CalculatePollingWaitTime( | 224 syncer_thread.CalculatePollingWaitTime( |
| 294 status, | 225 status, |
| 295 4, | 226 4, |
| 296 &user_idle_milliseconds_param, | 227 &user_idle_milliseconds_param, |
| 297 &continue_sync_cycle_param)); | 228 &continue_sync_cycle_param)); |
| 298 ASSERT_FALSE(continue_sync_cycle_param); | 229 ASSERT_FALSE(continue_sync_cycle_param); |
| 299 } | 230 } |
| 300 | 231 |
| 301 // Regression for exponential backoff reset when the syncer is nudged. | 232 // Regression for exponential backoff reset when the syncer is nudged. |
| 302 { | 233 { |
| 303 AllStatus::Status status = {}; | 234 AllStatus::Status status = {}; |
| 304 status.unsynced_count = 1; | 235 status.unsynced_count = 1; |
| 305 bool continue_sync_cycle_param = false; | 236 bool continue_sync_cycle_param = false; |
| 306 | 237 |
| 307 // Expect move from default polling interval to exponential backoff due to | 238 // Expect move from default polling interval to exponential backoff due to |
| 308 // unsynced_count != 0. | 239 // unsynced_count != 0. |
| 309 ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime( | 240 ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime( |
| 310 status, | 241 status, |
| 311 3600, | 242 3600, |
| 312 &user_idle_milliseconds_param, | 243 &user_idle_milliseconds_param, |
| 313 &continue_sync_cycle_param)); | 244 &continue_sync_cycle_param)); |
| 314 ASSERT_TRUE(continue_sync_cycle_param); | 245 ASSERT_TRUE(continue_sync_cycle_param); |
| 315 | 246 |
| 316 continue_sync_cycle_param = false; | 247 continue_sync_cycle_param = false; |
| 317 ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime( | 248 ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime( |
| 318 status, | 249 status, |
| 319 3600, | 250 3600, |
| 320 &user_idle_milliseconds_param, | 251 &user_idle_milliseconds_param, |
| 321 &continue_sync_cycle_param)); | 252 &continue_sync_cycle_param)); |
| 322 ASSERT_TRUE(continue_sync_cycle_param); | 253 ASSERT_TRUE(continue_sync_cycle_param); |
| 323 | 254 |
| 324 // Expect exponential backoff. | 255 // Expect exponential backoff. |
| 325 ASSERT_LE(2, syncer_thread->CalculatePollingWaitTime( | 256 ASSERT_LE(2, syncer_thread.CalculatePollingWaitTime( |
| 326 status, | 257 status, |
| 327 2, | 258 2, |
| 328 &user_idle_milliseconds_param, | 259 &user_idle_milliseconds_param, |
| 329 &continue_sync_cycle_param)); | 260 &continue_sync_cycle_param)); |
| 330 ASSERT_GE(6, syncer_thread->CalculatePollingWaitTime( | 261 ASSERT_GE(6, syncer_thread.CalculatePollingWaitTime( |
| 331 status, | 262 status, |
| 332 2, | 263 2, |
| 333 &user_idle_milliseconds_param, | 264 &user_idle_milliseconds_param, |
| 334 &continue_sync_cycle_param)); | 265 &continue_sync_cycle_param)); |
| 335 ASSERT_TRUE(continue_sync_cycle_param); | 266 ASSERT_TRUE(continue_sync_cycle_param); |
| 336 | 267 |
| 337 // A nudge resets the continue_sync_cycle_param value, so our backoff | 268 // A nudge resets the continue_sync_cycle_param value, so our backoff |
| 338 // should return to the minimum. | 269 // should return to the minimum. |
| 339 continue_sync_cycle_param = false; | 270 continue_sync_cycle_param = false; |
| 340 ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime( | 271 ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime( |
| 341 status, | 272 status, |
| 342 3600, | 273 3600, |
| 343 &user_idle_milliseconds_param, | 274 &user_idle_milliseconds_param, |
| 344 &continue_sync_cycle_param)); | 275 &continue_sync_cycle_param)); |
| 345 ASSERT_TRUE(continue_sync_cycle_param); | 276 ASSERT_TRUE(continue_sync_cycle_param); |
| 346 | 277 |
| 347 continue_sync_cycle_param = false; | 278 continue_sync_cycle_param = false; |
| 348 ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime( | 279 ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime( |
| 349 status, | 280 status, |
| 350 3600, | 281 3600, |
| 351 &user_idle_milliseconds_param, | 282 &user_idle_milliseconds_param, |
| 352 &continue_sync_cycle_param)); | 283 &continue_sync_cycle_param)); |
| 353 ASSERT_TRUE(continue_sync_cycle_param); | 284 ASSERT_TRUE(continue_sync_cycle_param); |
| 354 | 285 |
| 355 // Setting unsynced_count = 0 returns us to the default polling interval. | 286 // Setting unsynced_count = 0 returns us to the default polling interval. |
| 356 status.unsynced_count = 0; | 287 status.unsynced_count = 0; |
| 357 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, | 288 ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds, |
| 358 syncer_thread->CalculatePollingWaitTime( | 289 syncer_thread.CalculatePollingWaitTime( |
| 359 status, | 290 status, |
| 360 4, | 291 4, |
| 361 &user_idle_milliseconds_param, | 292 &user_idle_milliseconds_param, |
| 362 &continue_sync_cycle_param)); | 293 &continue_sync_cycle_param)); |
| 363 ASSERT_FALSE(continue_sync_cycle_param); | 294 ASSERT_FALSE(continue_sync_cycle_param); |
| 364 } | 295 } |
| 365 } | 296 } |
| 366 | 297 |
| 367 TEST_F(SyncerThreadWithSyncerTest, Polling) { | |
| 368 SyncShareIntercept interceptor; | |
| 369 connection()->SetMidCommitObserver(&interceptor); | |
| 370 | |
| 371 const TimeDelta poll_interval = TimeDelta::FromSeconds(1); | |
| 372 syncer_thread()->SetSyncerShortPollInterval(poll_interval); | |
| 373 EXPECT_TRUE(syncer_thread()->Start()); | |
| 374 | |
| 375 // Calling Open() should cause the SyncerThread to create a Syncer. | |
| 376 metadb()->Open(); | |
| 377 | |
| 378 TimeDelta two_polls = poll_interval + poll_interval; | |
| 379 // We could theoretically return immediately from the wait if the interceptor | |
| 380 // was already signaled for a SyncShare (the first one comes quick). | |
| 381 interceptor.WaitForSyncShare(1, two_polls); | |
| 382 EXPECT_FALSE(interceptor.times_sync_occured().empty()); | |
| 383 | |
| 384 // Wait for at least 2 more SyncShare operations. | |
| 385 interceptor.WaitForSyncShare(2, two_polls); | |
| 386 EXPECT_TRUE(syncer_thread()->Stop(2000)); | |
| 387 | |
| 388 // Now analyze the run. | |
| 389 std::vector<Time> data = interceptor.times_sync_occured(); | |
| 390 | |
| 391 EXPECT_GE(data.size(), static_cast<unsigned int>(3)); | |
| 392 for (unsigned int i = 0; i < data.size() - 1; i++) { | |
| 393 Time optimal_next_sync = data[i] + poll_interval; | |
| 394 // The pthreads impl uses a different time impl and is slightly (~900usecs) | |
| 395 // off, so this expectation can fail with --syncer-thread-pthreads. | |
| 396 EXPECT_TRUE(data[i + 1] >= optimal_next_sync) | |
| 397 << "difference is " | |
| 398 << (data[i + 1] - optimal_next_sync).InMicroseconds() << " usecs. " | |
| 399 << "~900usec delta is OK with --syncer-thread-pthreads"; | |
| 400 // This should be reliable, as there are no blocking or I/O operations | |
| 401 // except the explicit 2 second wait, so if it takes longer than this | |
| 402 // there is a problem. | |
| 403 EXPECT_TRUE(data[i + 1] < optimal_next_sync + poll_interval); | |
| 404 } | |
| 405 } | |
| 406 | |
| 407 TEST_F(SyncerThreadWithSyncerTest, Nudge) { | |
| 408 SyncShareIntercept interceptor; | |
| 409 connection()->SetMidCommitObserver(&interceptor); | |
| 410 // We don't want a poll to happen during this test (except the first one). | |
| 411 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); | |
| 412 syncer_thread()->SetSyncerShortPollInterval(poll_interval); | |
| 413 EXPECT_TRUE(syncer_thread()->Start()); | |
| 414 metadb()->Open(); | |
| 415 interceptor.WaitForSyncShare(1, poll_interval + poll_interval); | |
| 416 | |
| 417 EXPECT_EQ(static_cast<unsigned int>(1), | |
| 418 interceptor.times_sync_occured().size()); | |
| 419 // The SyncerThread should be waiting for the poll now. Nudge it to sync | |
| 420 // immediately (5ms). | |
| 421 syncer_thread()->NudgeSyncer(5, SyncerThread::kUnknown); | |
| 422 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); | |
| 423 EXPECT_EQ(static_cast<unsigned int>(2), | |
| 424 interceptor.times_sync_occured().size()); | |
| 425 | |
| 426 // SyncerThread should be waiting again. Signal it to stop. | |
| 427 EXPECT_TRUE(syncer_thread()->Stop(2000)); | |
| 428 } | |
| 429 | |
| 430 } // namespace browser_sync | 298 } // namespace browser_sync |
| OLD | NEW |