1// Copyright (c) 2011 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/memory/scoped_ptr.h" 7#include "base/task.h" 8#include "base/task_queue.h" 9#include "testing/gtest/include/gtest/gtest.h" 10 11namespace { 12 13// Sets bools according to whether Run or the destructor were called. 14class TrackCallsTask : public Task { 15 public: 16 TrackCallsTask(bool* ran, bool* deleted) 17 : ran_(ran), 18 deleted_(deleted) { 19 *ran_ = false; 20 *deleted_ = false; 21 } 22 23 virtual ~TrackCallsTask() { 24 *deleted_ = true; 25 } 26 27 virtual void Run() { 28 *ran_ = true; 29 } 30 31 private: 32 bool* ran_; 33 bool* deleted_; 34 35 DISALLOW_COPY_AND_ASSIGN(TrackCallsTask); 36}; 37 38// Adds a given task to the queue when run. 39class TaskQueuerTask : public Task { 40 public: 41 TaskQueuerTask(TaskQueue* queue, Task* task_to_queue) 42 : queue_(queue), 43 task_to_queue_(task_to_queue) { 44 } 45 46 virtual void Run() { 47 queue_->Push(task_to_queue_); 48 } 49 50 private: 51 TaskQueue* queue_; 52 Task* task_to_queue_; 53 54 DISALLOW_COPY_AND_ASSIGN(TaskQueuerTask); 55}; 56 57} // namespace 58 59TEST(TaskQueueTest, RunNoTasks) { 60 TaskQueue queue; 61 EXPECT_TRUE(queue.IsEmpty()); 62 63 queue.Run(); 64 EXPECT_TRUE(queue.IsEmpty()); 65} 66 67TEST(TaskQueueTest, RunTasks) { 68 TaskQueue queue; 69 70 bool ran_task1 = false; 71 bool deleted_task1 = false; 72 queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1)); 73 74 bool ran_task2 = false; 75 bool deleted_task2 = false; 76 queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2)); 77 78 queue.Run(); 79 80 EXPECT_TRUE(ran_task1); 81 EXPECT_TRUE(deleted_task1); 82 EXPECT_TRUE(ran_task2); 83 EXPECT_TRUE(deleted_task2); 84 EXPECT_TRUE(queue.IsEmpty()); 85} 86 87TEST(TaskQueueTest, ClearTasks) { 88 TaskQueue queue; 89 90 bool ran_task1 = false; 91 bool deleted_task1 = false; 92 queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1)); 93 94 bool ran_task2 = false; 95 bool deleted_task2 = false; 96 queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2)); 97 98 queue.Clear(); 99 100 EXPECT_TRUE(queue.IsEmpty()); 101 102 queue.Run(); 103 104 EXPECT_FALSE(ran_task1); 105 EXPECT_TRUE(deleted_task1); 106 EXPECT_FALSE(ran_task2); 107 EXPECT_TRUE(deleted_task2); 108 EXPECT_TRUE(queue.IsEmpty()); 109} 110 111TEST(TaskQueueTest, OneTaskQueuesMore) { 112 TaskQueue main_queue; 113 114 // Build a task which will queue two more when run. 115 scoped_ptr<TaskQueue> nested_queue(new TaskQueue()); 116 bool ran_task1 = false; 117 bool deleted_task1 = false; 118 nested_queue->Push( 119 new TaskQueuerTask(&main_queue, 120 new TrackCallsTask(&ran_task1, &deleted_task1))); 121 bool ran_task2 = false; 122 bool deleted_task2 = false; 123 nested_queue->Push( 124 new TaskQueuerTask(&main_queue, 125 new TrackCallsTask(&ran_task2, &deleted_task2))); 126 127 main_queue.Push(nested_queue.release()); 128 129 // Run the task which pushes two more tasks. 130 main_queue.Run(); 131 132 // None of the pushed tasks shoudl have run yet. 133 EXPECT_FALSE(ran_task1); 134 EXPECT_FALSE(deleted_task1); 135 EXPECT_FALSE(ran_task2); 136 EXPECT_FALSE(deleted_task2); 137 EXPECT_FALSE(main_queue.IsEmpty()); 138 139 // Now run the nested tasks. 140 main_queue.Run(); 141 142 EXPECT_TRUE(ran_task1); 143 EXPECT_TRUE(deleted_task1); 144 EXPECT_TRUE(ran_task2); 145 EXPECT_TRUE(deleted_task2); 146 EXPECT_TRUE(main_queue.IsEmpty()); 147} 148