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 11 namespace { 12 13 // Sets bools according to whether Run or the destructor were called. 14 class 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. 39 class 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 59 TEST(TaskQueueTest, RunNoTasks) { 60 TaskQueue queue; 61 EXPECT_TRUE(queue.IsEmpty()); 62 63 queue.Run(); 64 EXPECT_TRUE(queue.IsEmpty()); 65 } 66 67 TEST(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 87 TEST(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 111 TEST(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