Index: chrome/browser/sync_file_system/sync_process_runner_unittest.cc |
diff --git a/chrome/browser/sync_file_system/sync_process_runner_unittest.cc b/chrome/browser/sync_file_system/sync_process_runner_unittest.cc |
index 5984c272ffccb4e5bccc89f4d7abac54e9a5e0d0..9b929d522bdb9059b6a0e93c1bf913e300a7db1c 100644 |
--- a/chrome/browser/sync_file_system/sync_process_runner_unittest.cc |
+++ b/chrome/browser/sync_file_system/sync_process_runner_unittest.cc |
@@ -4,6 +4,8 @@ |
#include "chrome/browser/sync_file_system/sync_process_runner.h" |
+#include <deque> |
peria
2014/07/14 05:19:30
no mandatory: <queue>?
tzik
2014/07/14 06:12:49
Done.
|
+ |
#include "base/memory/scoped_ptr.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -85,15 +87,16 @@ class FakeSyncProcessRunner : public SyncProcessRunner { |
public: |
FakeSyncProcessRunner(SyncProcessRunner::Client* client, |
scoped_ptr<TimerHelper> timer_helper, |
- int max_parallel_task) |
+ size_t max_parallel_task) |
: SyncProcessRunner("FakeSyncProcess", |
client, timer_helper.Pass(), |
- max_parallel_task) { |
+ max_parallel_task), |
+ max_parallel_task_(max_parallel_task) { |
} |
virtual void StartSync(const SyncStatusCallback& callback) OVERRIDE { |
- EXPECT_TRUE(running_task_.is_null()); |
- running_task_ = callback; |
+ EXPECT_LT(running_tasks_.size(), max_parallel_task_); |
+ running_tasks_.push_back(callback); |
} |
virtual ~FakeSyncProcessRunner() { |
@@ -104,18 +107,19 @@ class FakeSyncProcessRunner : public SyncProcessRunner { |
} |
void CompleteTask(SyncStatusCode status) { |
- ASSERT_FALSE(running_task_.is_null()); |
- SyncStatusCallback task = running_task_; |
- running_task_.Reset(); |
+ ASSERT_FALSE(running_tasks_.empty()); |
+ SyncStatusCallback task = running_tasks_.front(); |
+ running_tasks_.pop_front(); |
task.Run(status); |
} |
bool HasRunningTask() const { |
- return !running_task_.is_null(); |
+ return !running_tasks_.empty(); |
} |
private: |
- SyncStatusCallback running_task_; |
+ size_t max_parallel_task_; |
+ std::deque<SyncStatusCallback> running_tasks_; |
DISALLOW_COPY_AND_ASSIGN(FakeSyncProcessRunner); |
}; |
@@ -184,6 +188,90 @@ TEST(SyncProcessRunnerTest, SingleTaskBasicTest) { |
fake_runner.CompleteTask(SYNC_STATUS_OK); |
EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds, |
fake_timer->GetCurrentDelay()); |
+ |
+ // Schedule the next with the longest delay if the client is persistently |
+ // unavailable. |
+ fake_client.set_service_state(SYNC_SERVICE_AUTHENTICATION_REQUIRED); |
+ fake_runner.UpdateChanges(100); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+} |
+ |
+TEST(SyncProcessRunnerTest, MultiTaskBasicTest) { |
+ FakeClient fake_client; |
+ FakeTimerHelper* fake_timer = new FakeTimerHelper(); |
+ FakeSyncProcessRunner fake_runner( |
+ &fake_client, |
+ scoped_ptr<SyncProcessRunner::TimerHelper>(fake_timer), |
+ 2 /* max_parallel_task */); |
+ |
+ base::TimeTicks base_time = base::TimeTicks::Now(); |
+ fake_timer->SetCurrentTime(base_time); |
+ |
+ EXPECT_FALSE(fake_timer->IsRunning()); |
+ |
+ fake_runner.UpdateChanges(100); |
+ EXPECT_TRUE(fake_timer->IsRunning()); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // Even after a task starts running, SyncProcessRunner should schedule next |
+ // task until the number of running task reachs the limit. |
+ fake_timer->AdvanceToScheduledTime(); |
+ EXPECT_TRUE(fake_timer->IsRunning()); |
+ EXPECT_TRUE(fake_runner.HasRunningTask()); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // After the second task starts running, SyncProcessRunner should stop |
+ // scheduling a task. |
+ fake_timer->AdvanceToScheduledTime(); |
+ EXPECT_FALSE(fake_timer->IsRunning()); |
+ EXPECT_TRUE(fake_runner.HasRunningTask()); |
+ |
+ fake_runner.CompleteTask(SYNC_STATUS_OK); |
+ EXPECT_TRUE(fake_timer->IsRunning()); |
+ EXPECT_TRUE(fake_runner.HasRunningTask()); |
+ fake_runner.CompleteTask(SYNC_STATUS_OK); |
+ EXPECT_TRUE(fake_timer->IsRunning()); |
+ EXPECT_FALSE(fake_runner.HasRunningTask()); |
+ |
+ // Turn |service_state| to TEMPORARY_UNAVAILABLE and let the task fail. |
+ // |fake_runner| should schedule following tasks with longer delay. |
+ fake_timer->AdvanceToScheduledTime(); |
+ fake_timer->AdvanceToScheduledTime(); |
+ fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE); |
+ fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // Consecutive error reports shouldn't extend delay immediately. |
+ fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // The next task will run after throttle period is over. |
+ // And its failure should extend the throttle period by twice. |
+ fake_timer->AdvanceToScheduledTime(); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
+ EXPECT_EQ(2 * SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // Next successful task should clear the throttling. |
+ fake_timer->AdvanceToScheduledTime(); |
+ fake_client.set_service_state(SYNC_SERVICE_RUNNING); |
+ fake_runner.CompleteTask(SYNC_STATUS_OK); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
+ |
+ // Then, following failing task should not extend throttling period. |
+ fake_timer->AdvanceToScheduledTime(); |
+ fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE); |
+ fake_runner.CompleteTask(SYNC_STATUS_FAILED); |
+ EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds, |
+ fake_timer->GetCurrentDelay()); |
} |
} // namespace sync_file_system |