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

Side by Side Diff: base/test/sequenced_task_runner_test_template.h

Issue 9663075: Implementation of SequencedTaskRunner based on SequencedWorkerPool. (Closed) Base URL: http://src.chromium.org/svn/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
Property Changes:
Added: svn:eol-style
+ LF
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 // This class defines tests that implementations of SequencedTaskRunner should
6 // pass in order to be conformant. See task_runner_test_template.h for a
7 // description of how to use the constructs in this file; these work the same.
8
9 #ifndef BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_
10 #define BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_
11 #pragma once
12
13 #include <cstddef>
14 #include <iosfwd>
15 #include <vector>
16
17 #include "base/basictypes.h"
18 #include "base/bind.h"
19 #include "base/callback.h"
20 #include "base/memory/ref_counted.h"
21 #include "base/sequenced_task_runner.h"
22 #include "base/synchronization/lock.h"
23 #include "base/time.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace base {
27
28 namespace internal {
29
30 // Utility class used in the tests below.
31 class SequencedTaskTracker : public RefCountedThreadSafe<SequencedTaskTracker> {
32 public:
33 struct TaskEvent {
akalin 2012/03/26 18:44:08 just pull out this struct, since it's already in a
Francois 2012/03/28 14:32:42 Done.
34 enum Type { POST, START, END };
35 TaskEvent(int i_in, Type type_in);
akalin 2012/03/26 18:44:08 don't use _in, just name them the same
akalin 2012/03/26 18:44:08 define a default constructor and initialize both v
Francois 2012/03/28 14:32:42 Done.
Francois 2012/03/28 14:32:42 Why define a default constructor if it never gets
akalin 2012/03/29 18:44:38 Just defensive coding; the same reason why it's su
36 int i;
37 Type type;
38 };
39
40 SequencedTaskTracker();
41
42 // Posts the non-nestable task |task|, and records its post event.
43 void PostWrappedNonNestableTask(
akalin 2012/03/26 18:44:08 the index (int i) should be a member of these func
Francois 2012/03/28 14:32:42 Please see my comment right at the bottom.
44 const scoped_refptr<SequencedTaskRunner>& task_runner,
45 const Closure& task);
46
47 // Posts the nestable task |task|, and records its post event.
48 void PostWrappedNestableTask(
49 const scoped_refptr<SequencedTaskRunner>& task_runner,
50 const Closure& task);
51
52 // Posts the delayed non-nestable task |task|, and records its post event.
53 void PostWrappedDelayedNonNestableTask(
54 const scoped_refptr<SequencedTaskRunner>& task_runner,
55 const Closure& task,
56 TimeDelta delay);
57
58 // Posts |task_count| non-nestable tasks.
59 void PostNonNestableTasks(
60 const scoped_refptr<SequencedTaskRunner>& task_runner,
61 int task_count);
62
63 const std::vector<TaskEvent>& GetTaskEvents() const;
64
65 private:
66 friend class RefCountedThreadSafe<SequencedTaskTracker>;
67
68 ~SequencedTaskTracker();
69
70 // A task which runs |task|, recording the start and end events.
71 void RunTask(const Closure& task, int task_i);
72
73 // Records a post event for task |i|. The owner is expected to be holding
74 // |lock_| (unlike |TaskStarted| and |TaskEnded|).
75 void TaskPosted(int i);
76
77 // Records a start event for task |i|.
78 void TaskStarted(int i);
79
80 // Records a end event for task |i|.
81 void TaskEnded(int i);
82
83 // Protects events_ and next_post_i_.
akalin 2012/03/26 18:44:08 events_ only
Francois 2012/03/28 14:32:42 Please see my comment right at the bottom.
84 Lock lock_;
85
86 // The events as they occurred for each task (protected by lock_).
87 std::vector<TaskEvent> events_;
88
89 // The ordinal to be used for the next task-posting task (protected by
90 // lock_).
91 int next_post_i_;
akalin 2012/03/26 18:44:08 remove the need for this, since the index should b
Francois 2012/03/28 14:32:42 Please see my comment right at the bottom.
92
93 DISALLOW_COPY_AND_ASSIGN(SequencedTaskTracker);
94 };
95
96 void PrintTo(const SequencedTaskTracker::TaskEvent& event, std::ostream* os);
97
98 void SleepForOneSecond();
99
100 // Checks the non-nestable task invariants for all tasks in |events|.
101 //
102 // The invariants are:
103 // 1) Events started and ended in the same order that they were posted.
104 // 2) Events for an individual tasks occur in the order {POST, START, END},
105 // and there is only one instance of each event type for a task.
106 // 3) The only events between a task's START and END events are the POSTs of
107 // other tasks. I.e. tasks were run sequentially, not interleaved.
108 ::testing::AssertionResult CheckNonNestableInvariants(
109 const std::vector<SequencedTaskTracker::TaskEvent>& events,
110 int task_count);
111
112 } // namespace internal
113
114 template <typename TaskRunnerTestDelegate>
115 class SequencedTaskRunnerTest : public testing::Test {
116 protected:
117 SequencedTaskRunnerTest()
118 : task_tracker_(new internal::SequencedTaskTracker()) {}
119
120 const scoped_refptr<internal::SequencedTaskTracker> task_tracker_;
121 TaskRunnerTestDelegate delegate_;
122 };
123
124 TYPED_TEST_CASE_P(SequencedTaskRunnerTest);
125
126 // This test posts N non-nestable tasks in sequence, and expects them to run
127 // in FIFO order, with no part of any two tasks' execution
128 // overlapping. I.e. that each task starts only after the previously-posted
129 // one has finished.
130 TYPED_TEST_P(SequencedTaskRunnerTest, SequentialNonNestable) {
131 const int task_count = 1000;
132
133 this->delegate_.StartTaskRunner();
134 const scoped_refptr<SequencedTaskRunner> task_runner =
135 this->delegate_.GetTaskRunner();
136
137 this->task_tracker_->PostWrappedNonNestableTask(
138 task_runner, Bind(&internal::SleepForOneSecond));
akalin 2012/03/26 18:44:08 with the change above to pass i to PostWrappedNonN
Francois 2012/03/28 14:32:42 Please see my comment right at the bottom.
139 for (int i = 1; i < task_count; ++i) {
140 this->task_tracker_->PostWrappedNonNestableTask(task_runner, Closure());
141 }
142
143 this->delegate_.StopTaskRunner();
144
145 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
146 task_count));
147 }
148
149 // This test posts N nestable tasks in sequence. It has the same expectations
150 // as SequentialNonNestable because even though the tasks are nestable, they
151 // will not be run nestedly in this case.
152 TYPED_TEST_P(SequencedTaskRunnerTest, SequentialNestable) {
153 const int task_count = 1000;
154
155 this->delegate_.StartTaskRunner();
156 const scoped_refptr<SequencedTaskRunner> task_runner =
157 this->delegate_.GetTaskRunner();
158
159 this->task_tracker_->PostWrappedNestableTask(
160 task_runner,
161 Bind(&internal::SleepForOneSecond));
162 for (int i = 1; i < task_count; ++i) {
163 this->task_tracker_->PostWrappedNestableTask(task_runner, Closure());
164 }
165
166 this->delegate_.StopTaskRunner();
167
168 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
169 task_count));
170 }
171
172 // This test posts non-nestable tasks in order of increasing delay, and checks
173 // that that the tasks are run in FIFO order and that there is no execution
174 // overlap whatsoever between any two tasks.
175 TYPED_TEST_P(SequencedTaskRunnerTest, SequentialDelayedNonNestable) {
176 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
177 DLOG(INFO) << "This SequencedTaskRunner doesn't handle "
178 "non-zero delays; skipping";
179 return;
180 }
181
182 const int task_count = 20;
183 const int delay_increment_ms = 50;
184
185 this->delegate_.StartTaskRunner();
186 const scoped_refptr<SequencedTaskRunner> task_runner =
187 this->delegate_.GetTaskRunner();
188
189 for (int i = 0; i < task_count; ++i) {
190 this->task_tracker_->PostWrappedDelayedNonNestableTask(
191 task_runner,
192 Closure(),
193 TimeDelta::FromMilliseconds(delay_increment_ms * i));
194 }
195
196 this->delegate_.StopTaskRunner();
197
198 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
199 task_count));
200 }
201
202 // This test posts a fast, non-nestable task from within each of a number of
203 // slow, non-nestable tasks and checks that they all run in the sequence they
204 // were posted in and that there is no execution overlap whatsoever.
205 TYPED_TEST_P(SequencedTaskRunnerTest, NonNestablePostFromNonNestableTask) {
206 const int parent_count = 10;
207 const int children_per_parent = 10;
208
209 this->delegate_.StartTaskRunner();
210 const scoped_refptr<SequencedTaskRunner> task_runner =
211 this->delegate_.GetTaskRunner();
212
213 const int end = parent_count;
214 for (int i = 0; i < end; ++i) {
215 Closure task = Bind(
216 &internal::SequencedTaskTracker::PostNonNestableTasks,
217 this->task_tracker_,
218 task_runner,
219 children_per_parent);
akalin 2012/03/26 18:44:08 probably would have to pass in a start/end index f
Francois 2012/03/28 14:32:42 This won't work for tests (such as NonNestablePost
220 this->task_tracker_->PostWrappedNonNestableTask(task_runner, task);
221 }
222
223 this->delegate_.StopTaskRunner();
224
225 EXPECT_TRUE(CheckNonNestableInvariants(
226 this->task_tracker_->GetTaskEvents(),
227 parent_count * (children_per_parent + 1)));
228 }
229
230 // TODO(francoisk777@gmail.com) Add a test, similiar to the above, which runs
231 // some tasked nestedly (which should be implemented in the test
232 // delegate). Also add, to the the test delegate, a predicate which checks
233 // whether the implementation supports nested tasks.
234 //
235
236 REGISTER_TYPED_TEST_CASE_P(SequencedTaskRunnerTest,
237 SequentialNonNestable,
238 SequentialNestable,
239 SequentialDelayedNonNestable,
240 NonNestablePostFromNonNestableTask);
241
242 } // namespace base
243
244 #endif // BASE_TASK_RUNNER_TEST_TEMPLATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698