1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/basictypes.h" 6 #include "base/bind.h" 7 #include "base/memory/weak_ptr.h" 8 #include "base/message_loop/message_loop.h" 9 #include "chrome/browser/sync_file_system/sync_task_manager.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace sync_file_system { 13 14 namespace { 15 16 void IncrementAndAssign(int* counter, 17 SyncStatusCode* status_out, 18 SyncStatusCode status) { 19 ++(*counter); 20 *status_out = status; 21 } 22 23 class TaskManagerClient 24 : public SyncTaskManager::Client, 25 public base::SupportsWeakPtr<TaskManagerClient> { 26 public: 27 TaskManagerClient() 28 : maybe_schedule_next_task_count_(0), 29 task_scheduled_count_(0), 30 idle_task_scheduled_count_(0), 31 last_operation_status_(SYNC_STATUS_OK) { 32 task_manager_.reset(new SyncTaskManager(AsWeakPtr())); 33 task_manager_->Initialize(SYNC_STATUS_OK); 34 maybe_schedule_next_task_count_ = 0; 35 } 36 virtual ~TaskManagerClient() {} 37 38 // DriveFileSyncManager::Client overrides. 39 virtual void MaybeScheduleNextTask() OVERRIDE { 40 ++maybe_schedule_next_task_count_; 41 } 42 virtual void NotifyLastOperationStatus( 43 SyncStatusCode last_operation_status) OVERRIDE { 44 last_operation_status_ = last_operation_status; 45 } 46 47 void ScheduleTask(SyncStatusCode status_to_return, 48 const SyncStatusCallback& callback) { 49 task_manager_->ScheduleTask( 50 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(), 51 status_to_return, false /* idle */), 52 callback); 53 } 54 55 void ScheduleTaskIfIdle(SyncStatusCode status_to_return) { 56 task_manager_->ScheduleTaskIfIdle( 57 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(), 58 status_to_return, true /* idle */)); 59 } 60 61 int maybe_schedule_next_task_count() const { 62 return maybe_schedule_next_task_count_; 63 } 64 int task_scheduled_count() const { return task_scheduled_count_; } 65 int idle_task_scheduled_count() const { return idle_task_scheduled_count_; } 66 SyncStatusCode last_operation_status() const { 67 return last_operation_status_; 68 } 69 70 private: 71 void DoTask(SyncStatusCode status_to_return, 72 bool is_idle_task, 73 const SyncStatusCallback& callback) { 74 ++task_scheduled_count_; 75 if (is_idle_task) 76 ++idle_task_scheduled_count_; 77 base::MessageLoop::current()->PostTask( 78 FROM_HERE, base::Bind(callback, status_to_return)); 79 } 80 81 scoped_ptr<SyncTaskManager> task_manager_; 82 83 int maybe_schedule_next_task_count_; 84 int task_scheduled_count_; 85 int idle_task_scheduled_count_; 86 87 SyncStatusCode last_operation_status_; 88 }; 89 90 // Arbitrary non-default status values for testing. 91 const SyncStatusCode kStatus1 = SYNC_FILE_ERROR_NO_MEMORY; 92 const SyncStatusCode kStatus2 = SYNC_DATABASE_ERROR_NOT_FOUND; 93 94 } // namespace 95 96 TEST(SyncTaskManagerTest, ScheduleTask) { 97 base::MessageLoop message_loop; 98 TaskManagerClient client; 99 int callback_count = 0; 100 SyncStatusCode callback_status = SYNC_STATUS_OK; 101 102 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 103 &callback_count, 104 &callback_status)); 105 message_loop.RunUntilIdle(); 106 107 EXPECT_EQ(kStatus1, callback_status); 108 EXPECT_EQ(kStatus1, client.last_operation_status()); 109 110 EXPECT_EQ(1, callback_count); 111 EXPECT_EQ(1, client.maybe_schedule_next_task_count()); 112 EXPECT_EQ(1, client.task_scheduled_count()); 113 EXPECT_EQ(0, client.idle_task_scheduled_count()); 114 } 115 116 TEST(SyncTaskManagerTest, ScheduleTwoTasks) { 117 base::MessageLoop message_loop; 118 TaskManagerClient client; 119 int callback_count = 0; 120 SyncStatusCode callback_status = SYNC_STATUS_OK; 121 122 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 123 &callback_count, 124 &callback_status)); 125 client.ScheduleTask(kStatus2, base::Bind(&IncrementAndAssign, 126 &callback_count, 127 &callback_status)); 128 message_loop.RunUntilIdle(); 129 130 EXPECT_EQ(kStatus2, callback_status); 131 EXPECT_EQ(kStatus2, client.last_operation_status()); 132 133 EXPECT_EQ(2, callback_count); 134 EXPECT_EQ(1, client.maybe_schedule_next_task_count()); 135 EXPECT_EQ(2, client.task_scheduled_count()); 136 EXPECT_EQ(0, client.idle_task_scheduled_count()); 137 } 138 139 TEST(SyncTaskManagerTest, ScheduleIdleTask) { 140 base::MessageLoop message_loop; 141 TaskManagerClient client; 142 143 client.ScheduleTaskIfIdle(kStatus1); 144 message_loop.RunUntilIdle(); 145 146 EXPECT_EQ(kStatus1, client.last_operation_status()); 147 148 EXPECT_EQ(1, client.maybe_schedule_next_task_count()); 149 EXPECT_EQ(1, client.task_scheduled_count()); 150 EXPECT_EQ(1, client.idle_task_scheduled_count()); 151 } 152 153 TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) { 154 base::MessageLoop message_loop; 155 TaskManagerClient client; 156 int callback_count = 0; 157 SyncStatusCode callback_status = SYNC_STATUS_OK; 158 159 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 160 &callback_count, 161 &callback_status)); 162 client.ScheduleTaskIfIdle(kStatus2); 163 message_loop.RunUntilIdle(); 164 165 // Idle task must not have run. 166 EXPECT_EQ(kStatus1, callback_status); 167 EXPECT_EQ(kStatus1, client.last_operation_status()); 168 169 EXPECT_EQ(1, callback_count); 170 EXPECT_EQ(1, client.maybe_schedule_next_task_count()); 171 EXPECT_EQ(1, client.task_scheduled_count()); 172 EXPECT_EQ(0, client.idle_task_scheduled_count()); 173 } 174 175 } // namespace sync_file_system 176