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

Side by Side Diff: base/task_runner_test_template.h

Issue 9592037: Implement SequencedWorkerPool::RunsTasksOnCurrentThread() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months 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 | « no previous file | base/task_runner_test_template.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This class defines tests that implementations of TaskRunner should 5 // This class defines tests that implementations of TaskRunner should
6 // pass in order to be conformant. Here's how you use it to test your 6 // pass in order to be conformant. Here's how you use it to test your
7 // implementation. 7 // implementation.
8 // 8 //
9 // Say your class is called MyTaskRunner. Then you need to define a 9 // Say your class is called MyTaskRunner. Then you need to define a
10 // class called MyTaskRunnerTestDelegate in my_task_runner_unittest.cc 10 // class called MyTaskRunnerTestDelegate in my_task_runner_unittest.cc
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 50
51 #ifndef BASE_TASK_RUNNER_TEST_TEMPLATE_H_ 51 #ifndef BASE_TASK_RUNNER_TEST_TEMPLATE_H_
52 #define BASE_TASK_RUNNER_TEST_TEMPLATE_H_ 52 #define BASE_TASK_RUNNER_TEST_TEMPLATE_H_
53 #pragma once 53 #pragma once
54 54
55 #include <cstddef> 55 #include <cstddef>
56 #include <map> 56 #include <map>
57 57
58 #include "base/basictypes.h" 58 #include "base/basictypes.h"
59 #include "base/bind.h" 59 #include "base/bind.h"
60 #include "base/callback.h"
60 #include "base/memory/ref_counted.h" 61 #include "base/memory/ref_counted.h"
61 #include "base/synchronization/lock.h" 62 #include "base/synchronization/lock.h"
62 #include "base/task_runner.h" 63 #include "base/task_runner.h"
64 #include "base/threading/thread.h"
63 #include "base/tracked_objects.h" 65 #include "base/tracked_objects.h"
64 #include "testing/gtest/include/gtest/gtest.h" 66 #include "testing/gtest/include/gtest/gtest.h"
65 67
66 namespace base { 68 namespace base {
67 69
68 // Utility class used in the tests below. 70 namespace internal {
71
72 // Utility class that keeps track of how many times particular tasks
73 // are run.
69 class TaskTracker : public RefCountedThreadSafe<TaskTracker> { 74 class TaskTracker : public RefCountedThreadSafe<TaskTracker> {
70 public: 75 public:
71 TaskTracker(); 76 TaskTracker();
72 77
73 void RunTask(int i); 78 // Returns a closure that runs the given task and increments the run
79 // count of |i| by one. |task| may be null. It is guaranteed that
80 // only one task wrapped by a given tracker will be run at a time.
81 Closure WrapTask(const Closure& task, int i);
74 82
75 std::map<int, int> GetTaskRunCounts() const; 83 std::map<int, int> GetTaskRunCounts() const;
76 84
77 private: 85 private:
78 friend class RefCountedThreadSafe<TaskTracker>; 86 friend class RefCountedThreadSafe<TaskTracker>;
79 87
80 ~TaskTracker(); 88 ~TaskTracker();
81 89
90 void RunTask(const Closure& task, int i);
91
82 mutable Lock task_run_counts_lock_; 92 mutable Lock task_run_counts_lock_;
83 std::map<int, int> task_run_counts_; 93 std::map<int, int> task_run_counts_;
84 94
85 DISALLOW_COPY_AND_ASSIGN(TaskTracker); 95 DISALLOW_COPY_AND_ASSIGN(TaskTracker);
86 }; 96 };
87 97
98 } // namespace internal
99
88 template <typename TaskRunnerTestDelegate> 100 template <typename TaskRunnerTestDelegate>
89 class TaskRunnerTest : public testing::Test { 101 class TaskRunnerTest : public testing::Test {
90 protected: 102 protected:
91 TaskRunnerTest() : task_tracker_(new TaskTracker()) {} 103 TaskRunnerTest() : task_tracker_(new internal::TaskTracker()) {}
92 104
93 const scoped_refptr<TaskTracker> task_tracker_; 105 const scoped_refptr<internal::TaskTracker> task_tracker_;
94 TaskRunnerTestDelegate delegate_; 106 TaskRunnerTestDelegate delegate_;
95 }; 107 };
96 108
97 TYPED_TEST_CASE_P(TaskRunnerTest); 109 TYPED_TEST_CASE_P(TaskRunnerTest);
98 110
99 // We can't really test much, since TaskRunner provides very few 111 // We can't really test much, since TaskRunner provides very few
100 // guarantees. 112 // guarantees.
101 113
102 // Post a bunch of tasks to the task runner. They should all 114 // Post a bunch of tasks to the task runner. They should all
103 // complete. 115 // complete.
104 TYPED_TEST_P(TaskRunnerTest, Basic) { 116 TYPED_TEST_P(TaskRunnerTest, Basic) {
105 std::map<int, int> expected_task_run_counts; 117 std::map<int, int> expected_task_run_counts;
106 118
107 this->delegate_.StartTaskRunner(); 119 this->delegate_.StartTaskRunner();
108 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); 120 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner();
109 // Post each ith task i+1 times. 121 // Post each ith task i+1 times.
110 for (int i = 0; i < 20; ++i) { 122 for (int i = 0; i < 20; ++i) {
111 Closure task = Bind(&TaskTracker::RunTask, this->task_tracker_, i); 123 const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i);
112 for (int j = 0; j < i + 1; ++j) { 124 for (int j = 0; j < i + 1; ++j) {
113 task_runner->PostTask(FROM_HERE, task); 125 task_runner->PostTask(FROM_HERE, ith_task);
114 ++expected_task_run_counts[i]; 126 ++expected_task_run_counts[i];
115 } 127 }
116 } 128 }
117 this->delegate_.StopTaskRunner(); 129 this->delegate_.StopTaskRunner();
118 130
119 EXPECT_EQ(expected_task_run_counts, 131 EXPECT_EQ(expected_task_run_counts,
120 this->task_tracker_->GetTaskRunCounts()); 132 this->task_tracker_->GetTaskRunCounts());
121 } 133 }
122 134
123 // Post a bunch of delayed tasks to the task runner. They should all 135 // Post a bunch of delayed tasks to the task runner. They should all
124 // complete. 136 // complete.
125 TYPED_TEST_P(TaskRunnerTest, Delayed) { 137 TYPED_TEST_P(TaskRunnerTest, Delayed) {
126 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { 138 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
127 DLOG(INFO) << "This TaskRunner doesn't handle non-zero delays; skipping"; 139 DLOG(INFO) << "This TaskRunner doesn't handle non-zero delays; skipping";
128 return; 140 return;
129 } 141 }
130 142
131 std::map<int, int> expected_task_run_counts; 143 std::map<int, int> expected_task_run_counts;
132 144
133 this->delegate_.StartTaskRunner(); 145 this->delegate_.StartTaskRunner();
134 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); 146 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner();
135 // Post each ith task i+1 times with delays from 0-i. 147 // Post each ith task i+1 times with delays from 0-i.
136 for (int i = 0; i < 20; ++i) { 148 for (int i = 0; i < 20; ++i) {
137 Closure task = Bind(&TaskTracker::RunTask, this->task_tracker_, i); 149 const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i);
138 for (int j = 0; j < i + 1; ++j) { 150 for (int j = 0; j < i + 1; ++j) {
139 task_runner->PostDelayedTask(FROM_HERE, task, j); 151 task_runner->PostDelayedTask(FROM_HERE, ith_task, j);
140 ++expected_task_run_counts[i]; 152 ++expected_task_run_counts[i];
141 } 153 }
142 } 154 }
143 this->delegate_.StopTaskRunner(); 155 this->delegate_.StopTaskRunner();
144 156
145 EXPECT_EQ(expected_task_run_counts, 157 EXPECT_EQ(expected_task_run_counts,
146 this->task_tracker_->GetTaskRunCounts()); 158 this->task_tracker_->GetTaskRunCounts());
147 } 159 }
148 160
149 // TODO(akalin): Add test to verify RunsTaskOnCurrentThread() returns 161 namespace internal {
150 // true for tasks runs on the TaskRunner and returns false on a
151 // separate PlatformThread.
152 162
153 REGISTER_TYPED_TEST_CASE_P(TaskRunnerTest, Basic, Delayed); 163 // Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to
164 // equal |expected_value|.
165 void ExpectRunsTasksOnCurrentThread(
166 bool expected_value,
167 const scoped_refptr<TaskRunner>& task_runner);
168
169 } // namespace internal
170
171 // Post a bunch of tasks to the task runner as well as to a separate
172 // thread, each checking the value of RunsTasksOnCurrentThread(),
173 // which should return true for the tasks posted on the task runner
174 // and false for the tasks posted on the separate thread.
175 TYPED_TEST_P(TaskRunnerTest, RunsTasksOnCurrentThread) {
176 std::map<int, int> expected_task_run_counts;
177
178 Thread thread("Non-task-runner thread");
179 ASSERT_TRUE(thread.Start());
180 this->delegate_.StartTaskRunner();
181
182 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner();
183 // Post each ith task i+1 times on the task runner and i+1 times on
184 // the non-task-runner thread.
185 for (int i = 0; i < 20; ++i) {
186 const Closure& ith_task_runner_task =
187 this->task_tracker_->WrapTask(
188 Bind(&internal::ExpectRunsTasksOnCurrentThread,
189 true, task_runner),
190 i);
191 const Closure& ith_non_task_runner_task =
192 this->task_tracker_->WrapTask(
193 Bind(&internal::ExpectRunsTasksOnCurrentThread,
194 false, task_runner),
195 i);
196 for (int j = 0; j < i + 1; ++j) {
197 task_runner->PostTask(FROM_HERE, ith_task_runner_task);
198 thread.message_loop()->PostTask(FROM_HERE, ith_non_task_runner_task);
199 expected_task_run_counts[i] += 2;
200 }
201 }
202
203 this->delegate_.StopTaskRunner();
204 thread.Stop();
205
206 EXPECT_EQ(expected_task_run_counts,
207 this->task_tracker_->GetTaskRunCounts());
208 }
209
210 REGISTER_TYPED_TEST_CASE_P(
211 TaskRunnerTest, Basic, Delayed, RunsTasksOnCurrentThread);
154 212
155 } // namespace base 213 } // namespace base
156 214
157 #endif //#define BASE_TASK_RUNNER_TEST_TEMPLATE_H_ 215 #endif //#define BASE_TASK_RUNNER_TEST_TEMPLATE_H_
OLDNEW
« no previous file with comments | « no previous file | base/task_runner_test_template.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698