OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/sync_file_system/sync_process_runner.h" | 5 #include "chrome/browser/sync_file_system/sync_process_runner.h" |
6 | 6 |
| 7 #include <queue> |
| 8 |
7 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
9 | 11 |
10 namespace sync_file_system { | 12 namespace sync_file_system { |
11 | 13 |
12 namespace { | 14 namespace { |
13 | 15 |
14 class FakeClient : public SyncProcessRunner::Client { | 16 class FakeClient : public SyncProcessRunner::Client { |
15 public: | 17 public: |
16 FakeClient() : service_state_(SYNC_SERVICE_RUNNING) {} | 18 FakeClient() : service_state_(SYNC_SERVICE_RUNNING) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 base::TimeTicks scheduled_time_; | 80 base::TimeTicks scheduled_time_; |
79 base::Closure timer_task_; | 81 base::Closure timer_task_; |
80 | 82 |
81 DISALLOW_COPY_AND_ASSIGN(FakeTimerHelper); | 83 DISALLOW_COPY_AND_ASSIGN(FakeTimerHelper); |
82 }; | 84 }; |
83 | 85 |
84 class FakeSyncProcessRunner : public SyncProcessRunner { | 86 class FakeSyncProcessRunner : public SyncProcessRunner { |
85 public: | 87 public: |
86 FakeSyncProcessRunner(SyncProcessRunner::Client* client, | 88 FakeSyncProcessRunner(SyncProcessRunner::Client* client, |
87 scoped_ptr<TimerHelper> timer_helper, | 89 scoped_ptr<TimerHelper> timer_helper, |
88 int max_parallel_task) | 90 size_t max_parallel_task) |
89 : SyncProcessRunner("FakeSyncProcess", | 91 : SyncProcessRunner("FakeSyncProcess", |
90 client, timer_helper.Pass(), | 92 client, timer_helper.Pass(), |
91 max_parallel_task) { | 93 max_parallel_task), |
| 94 max_parallel_task_(max_parallel_task) { |
92 } | 95 } |
93 | 96 |
94 virtual void StartSync(const SyncStatusCallback& callback) OVERRIDE { | 97 virtual void StartSync(const SyncStatusCallback& callback) OVERRIDE { |
95 EXPECT_TRUE(running_task_.is_null()); | 98 EXPECT_LT(running_tasks_.size(), max_parallel_task_); |
96 running_task_ = callback; | 99 running_tasks_.push(callback); |
97 } | 100 } |
98 | 101 |
99 virtual ~FakeSyncProcessRunner() { | 102 virtual ~FakeSyncProcessRunner() { |
100 } | 103 } |
101 | 104 |
102 void UpdateChanges(int num_changes) { | 105 void UpdateChanges(int num_changes) { |
103 OnChangesUpdated(num_changes); | 106 OnChangesUpdated(num_changes); |
104 } | 107 } |
105 | 108 |
106 void CompleteTask(SyncStatusCode status) { | 109 void CompleteTask(SyncStatusCode status) { |
107 ASSERT_FALSE(running_task_.is_null()); | 110 ASSERT_FALSE(running_tasks_.empty()); |
108 SyncStatusCallback task = running_task_; | 111 SyncStatusCallback task = running_tasks_.front(); |
109 running_task_.Reset(); | 112 running_tasks_.pop(); |
110 task.Run(status); | 113 task.Run(status); |
111 } | 114 } |
112 | 115 |
113 bool HasRunningTask() const { | 116 bool HasRunningTask() const { |
114 return !running_task_.is_null(); | 117 return !running_tasks_.empty(); |
115 } | 118 } |
116 | 119 |
117 private: | 120 private: |
118 SyncStatusCallback running_task_; | 121 size_t max_parallel_task_; |
| 122 std::queue<SyncStatusCallback> running_tasks_; |
119 | 123 |
120 DISALLOW_COPY_AND_ASSIGN(FakeSyncProcessRunner); | 124 DISALLOW_COPY_AND_ASSIGN(FakeSyncProcessRunner); |
121 }; | 125 }; |
122 | 126 |
123 } // namespace | 127 } // namespace |
124 | 128 |
125 TEST(SyncProcessRunnerTest, SingleTaskBasicTest) { | 129 TEST(SyncProcessRunnerTest, SingleTaskBasicTest) { |
126 FakeClient fake_client; | 130 FakeClient fake_client; |
127 FakeTimerHelper* fake_timer = new FakeTimerHelper(); | 131 FakeTimerHelper* fake_timer = new FakeTimerHelper(); |
128 FakeSyncProcessRunner fake_runner( | 132 FakeSyncProcessRunner fake_runner( |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, | 181 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
178 fake_timer->GetCurrentDelay()); | 182 fake_timer->GetCurrentDelay()); |
179 | 183 |
180 // There's no item to sync anymore, SyncProcessRunner should schedules the | 184 // There's no item to sync anymore, SyncProcessRunner should schedules the |
181 // next with the longest delay. | 185 // next with the longest delay. |
182 fake_runner.UpdateChanges(0); | 186 fake_runner.UpdateChanges(0); |
183 fake_timer->AdvanceToScheduledTime(); | 187 fake_timer->AdvanceToScheduledTime(); |
184 fake_runner.CompleteTask(SYNC_STATUS_OK); | 188 fake_runner.CompleteTask(SYNC_STATUS_OK); |
185 EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds, | 189 EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds, |
186 fake_timer->GetCurrentDelay()); | 190 fake_timer->GetCurrentDelay()); |
| 191 |
| 192 // Schedule the next with the longest delay if the client is persistently |
| 193 // unavailable. |
| 194 fake_client.set_service_state(SYNC_SERVICE_AUTHENTICATION_REQUIRED); |
| 195 fake_runner.UpdateChanges(100); |
| 196 EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds, |
| 197 fake_timer->GetCurrentDelay()); |
187 } | 198 } |
188 | 199 |
| 200 TEST(SyncProcessRunnerTest, MultiTaskBasicTest) { |
| 201 FakeClient fake_client; |
| 202 FakeTimerHelper* fake_timer = new FakeTimerHelper(); |
| 203 FakeSyncProcessRunner fake_runner( |
| 204 &fake_client, |
| 205 scoped_ptr<SyncProcessRunner::TimerHelper>(fake_timer), |
| 206 2 /* max_parallel_task */); |
| 207 |
| 208 base::TimeTicks base_time = base::TimeTicks::Now(); |
| 209 fake_timer->SetCurrentTime(base_time); |
| 210 |
| 211 EXPECT_FALSE(fake_timer->IsRunning()); |
| 212 |
| 213 fake_runner.UpdateChanges(100); |
| 214 EXPECT_TRUE(fake_timer->IsRunning()); |
| 215 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
| 216 fake_timer->GetCurrentDelay()); |
| 217 |
| 218 // Even after a task starts running, SyncProcessRunner should schedule next |
| 219 // task until the number of running task reachs the limit. |
| 220 fake_timer->AdvanceToScheduledTime(); |
| 221 EXPECT_TRUE(fake_timer->IsRunning()); |
| 222 EXPECT_TRUE(fake_runner.HasRunningTask()); |
| 223 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
| 224 fake_timer->GetCurrentDelay()); |
| 225 |
| 226 // After the second task starts running, SyncProcessRunner should stop |
| 227 // scheduling a task. |
| 228 fake_timer->AdvanceToScheduledTime(); |
| 229 EXPECT_FALSE(fake_timer->IsRunning()); |
| 230 EXPECT_TRUE(fake_runner.HasRunningTask()); |
| 231 |
| 232 fake_runner.CompleteTask(SYNC_STATUS_OK); |
| 233 EXPECT_TRUE(fake_timer->IsRunning()); |
| 234 EXPECT_TRUE(fake_runner.HasRunningTask()); |
| 235 fake_runner.CompleteTask(SYNC_STATUS_OK); |
| 236 EXPECT_TRUE(fake_timer->IsRunning()); |
| 237 EXPECT_FALSE(fake_runner.HasRunningTask()); |
| 238 |
| 239 // Turn |service_state| to TEMPORARY_UNAVAILABLE and let the task fail. |
| 240 // |fake_runner| should schedule following tasks with longer delay. |
| 241 fake_timer->AdvanceToScheduledTime(); |
| 242 fake_timer->AdvanceToScheduledTime(); |
| 243 fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE); |
| 244 fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
| 245 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
| 246 fake_timer->GetCurrentDelay()); |
| 247 |
| 248 // Consecutive error reports shouldn't extend delay immediately. |
| 249 fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
| 250 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
| 251 fake_timer->GetCurrentDelay()); |
| 252 |
| 253 // The next task will run after throttle period is over. |
| 254 // And its failure should extend the throttle period by twice. |
| 255 fake_timer->AdvanceToScheduledTime(); |
| 256 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
| 257 fake_timer->GetCurrentDelay()); |
| 258 fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
| 259 EXPECT_EQ(2 * SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
| 260 fake_timer->GetCurrentDelay()); |
| 261 |
| 262 // Next successful task should clear the throttling. |
| 263 fake_timer->AdvanceToScheduledTime(); |
| 264 fake_client.set_service_state(SYNC_SERVICE_RUNNING); |
| 265 fake_runner.CompleteTask(SYNC_STATUS_OK); |
| 266 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
| 267 fake_timer->GetCurrentDelay()); |
| 268 |
| 269 // Then, following failing task should not extend throttling period. |
| 270 fake_timer->AdvanceToScheduledTime(); |
| 271 fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE); |
| 272 fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
| 273 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
| 274 fake_timer->GetCurrentDelay()); |
| 275 } |
| 276 |
189 } // namespace sync_file_system | 277 } // namespace sync_file_system |
OLD | NEW |