Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: base/mac/libdispatch_task_runner_unittest.cc

Issue 11464009: Create LibDispatchTaskRunner, a SingleThreadTaskRunner that is backed by a libdispatch queue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: BASE_EXPORT Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/mac/libdispatch_task_runner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/mac/libdispatch_task_runner.h"
6
7 #include "base/bind.h"
8 #include "base/mac/bind_objc_block.h"
9 #include "base/message_loop.h"
10 #include "base/stringprintf.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 class LibDispatchTaskRunnerTest : public testing::Test {
14 public:
15 virtual void SetUp() OVERRIDE {
16 task_runner_ = new base::mac::LibDispatchTaskRunner(
17 "org.chromium.LibDispatchTaskRunnerTest");
18 }
19
20 // DispatchLastTask is used to run the main test thread's MessageLoop until
21 // all non-delayed tasks are run on the LibDispatchTaskRunner.
22 void DispatchLastTask() {
23 dispatch_async(task_runner_->GetDispatchQueue(), ^{
24 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure());
25 });
26 message_loop_.Run();
27 }
28
29 // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares
30 // them against the recorded values.
31 void VerifyTaskOrder(const char* const expectations[],
32 size_t num_expectations) {
33 size_t actual_size = task_order_.size();
34
35 for (size_t i = 0; i < num_expectations; ++i) {
36 if (i >= actual_size) {
37 EXPECT_LT(i, actual_size) << "Expected " << expectations[i];
38 continue;
39 }
40
41 EXPECT_EQ(expectations[i], task_order_[i]);
42 }
43
44 if (actual_size > num_expectations) {
45 EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:";
46 for (size_t i = num_expectations; i < actual_size; ++i) {
47 EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")";
48 }
49 }
50 }
51
52 // The message loop for the test main thread.
53 MessageLoop message_loop_;
54
55 // The task runner under test.
56 scoped_refptr<base::mac::LibDispatchTaskRunner> task_runner_;
57
58 // Vector that records data from TaskOrderMarker.
59 std::vector<std::string> task_order_;
60 };
61
62 // Scoper that records the beginning and end of a running task.
63 class TaskOrderMarker {
64 public:
65 TaskOrderMarker(LibDispatchTaskRunnerTest* test, const std::string& name)
66 : test_(test),
67 name_(name) {
68 test->task_order_.push_back(std::string("BEGIN ") + name);
69 }
70 ~TaskOrderMarker() {
71 test_->task_order_.push_back(std::string("END ") + name_);
72 }
73
74 private:
75 LibDispatchTaskRunnerTest* test_;
76 std::string name_;
77 };
78
79 void RecordTaskOrder(LibDispatchTaskRunnerTest* test, const std::string& name) {
80 TaskOrderMarker marker(test, name);
81 }
82
83 // Returns a closure that records the task order.
84 base::Closure BoundRecordTaskOrder(LibDispatchTaskRunnerTest* test,
85 const std::string& name) {
86 return base::Bind(&RecordTaskOrder, base::Unretained(test), name);
87 }
88
89 TEST_F(LibDispatchTaskRunnerTest, PostTask) {
90 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Basic Task"));
91 DispatchLastTask();
92 const char* const expectations[] = {
93 "BEGIN Basic Task",
94 "END Basic Task"
95 };
96 VerifyTaskOrder(expectations, arraysize(expectations));
97 }
98
99 TEST_F(LibDispatchTaskRunnerTest, PostTaskWithinTask) {
100 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
101 TaskOrderMarker marker(this, "Outer");
102 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Inner"));
103 }));
104 DispatchLastTask();
105
106 const char* const expectations[] = {
107 "BEGIN Outer",
108 "END Outer",
109 "BEGIN Inner",
110 "END Inner"
111 };
112 VerifyTaskOrder(expectations, arraysize(expectations));
113 }
114
115 TEST_F(LibDispatchTaskRunnerTest, NoMessageLoop) {
116 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
117 TaskOrderMarker marker(this,
118 base::StringPrintf("MessageLoop = %p", MessageLoop::current()));
119 }));
120 DispatchLastTask();
121
122 const char* const expectations[] = {
123 "BEGIN MessageLoop = 0x0",
124 "END MessageLoop = 0x0"
125 };
126 VerifyTaskOrder(expectations, arraysize(expectations));
127 }
128
129 TEST_F(LibDispatchTaskRunnerTest, DispatchAndPostTasks) {
130 dispatch_async(task_runner_->GetDispatchQueue(), ^{
131 TaskOrderMarker marker(this, "First Block");
132 task_runner_->PostTask(FROM_HERE,
133 BoundRecordTaskOrder(this, "Second Task"));
134 });
135 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First Task"));
136 dispatch_async(task_runner_->GetDispatchQueue(), ^{
137 TaskOrderMarker marker(this, "Second Block");
138 });
139 DispatchLastTask();
140
141 const char* const expectations[] = {
142 "BEGIN First Block",
143 "END First Block",
144 "BEGIN First Task",
145 "END First Task",
146 "BEGIN Second Block",
147 "END Second Block",
148 "BEGIN Second Task",
149 "END Second Task",
150 };
151 VerifyTaskOrder(expectations, arraysize(expectations));
152 }
153
154 TEST_F(LibDispatchTaskRunnerTest, NonNestable) {
155 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
156 TaskOrderMarker marker(this, "First");
157 task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{
158 TaskOrderMarker marker(this, "Third NonNestable");
159 }));
160 }));
161 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second"));
162 DispatchLastTask();
163
164 const char* const expectations[] = {
165 "BEGIN First",
166 "END First",
167 "BEGIN Second",
168 "END Second",
169 "BEGIN Third NonNestable",
170 "END Third NonNestable"
171 };
172 VerifyTaskOrder(expectations, arraysize(expectations));
173 }
174
175 TEST_F(LibDispatchTaskRunnerTest, PostDelayed) {
176 base::TimeTicks post_time;
177 __block base::TimeTicks run_time;
178 const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50);
179
180 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First"));
181 post_time = base::TimeTicks::Now();
182 task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{
183 TaskOrderMarker marker(this, "Timed");
184 run_time = base::TimeTicks::Now();
185 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure());
186 }), delta);
187 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second"));
188 message_loop_.Run();
189
190 const char* const expectations[] = {
191 "BEGIN First",
192 "END First",
193 "BEGIN Second",
194 "END Second",
195 "BEGIN Timed",
196 "END Timed",
197 };
198 VerifyTaskOrder(expectations, arraysize(expectations));
199
200 EXPECT_GE(run_time, post_time + delta);
201 }
OLDNEW
« no previous file with comments | « base/mac/libdispatch_task_runner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698