Home | History | Annotate | Download | only in sync_file_system
      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