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:
TrackCallsTask(bool * ran,bool * deleted)16 TrackCallsTask(bool* ran, bool* deleted)
17 : ran_(ran),
18 deleted_(deleted) {
19 *ran_ = false;
20 *deleted_ = false;
21 }
22
~TrackCallsTask()23 virtual ~TrackCallsTask() {
24 *deleted_ = true;
25 }
26
Run()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:
TaskQueuerTask(TaskQueue * queue,Task * task_to_queue)41 TaskQueuerTask(TaskQueue* queue, Task* task_to_queue)
42 : queue_(queue),
43 task_to_queue_(task_to_queue) {
44 }
45
Run()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
TEST(TaskQueueTest,RunNoTasks)59 TEST(TaskQueueTest, RunNoTasks) {
60 TaskQueue queue;
61 EXPECT_TRUE(queue.IsEmpty());
62
63 queue.Run();
64 EXPECT_TRUE(queue.IsEmpty());
65 }
66
TEST(TaskQueueTest,RunTasks)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
TEST(TaskQueueTest,ClearTasks)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
TEST(TaskQueueTest,OneTaskQueuesMore)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