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

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

Issue 11649032: Flush SequenceWorkerPool tasks after each unit test. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 10 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
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 SequencedTaskRunner should 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 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. 7 // description of how to use the constructs in this file; these work the same.
8 8
9 #ifndef BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_ 9 #ifndef BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_
10 #define BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_ 10 #define BASE_SEQUENCED_TASK_RUNNER_TEST_TEMPLATE_H_
11 11
12 #include <cstddef> 12 #include <cstddef>
13 #include <iosfwd> 13 #include <iosfwd>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/basictypes.h" 16 #include "base/basictypes.h"
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/callback.h" 18 #include "base/callback.h"
19 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
20 #include "base/sequenced_task_runner.h" 20 #include "base/sequenced_task_runner.h"
21 #include "base/synchronization/condition_variable.h"
21 #include "base/synchronization/lock.h" 22 #include "base/synchronization/lock.h"
22 #include "base/time.h" 23 #include "base/time.h"
23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
24 25
25 namespace base { 26 namespace base {
26 27
27 namespace internal { 28 namespace internal {
28 29
29 struct TaskEvent { 30 struct TaskEvent {
30 enum Type { POST, START, END }; 31 enum Type { POST, START, END };
(...skipping 23 matching lines...) Expand all
54 const Closure& task, 55 const Closure& task,
55 TimeDelta delay); 56 TimeDelta delay);
56 57
57 // Posts |task_count| non-nestable tasks. 58 // Posts |task_count| non-nestable tasks.
58 void PostNonNestableTasks( 59 void PostNonNestableTasks(
59 const scoped_refptr<SequencedTaskRunner>& task_runner, 60 const scoped_refptr<SequencedTaskRunner>& task_runner,
60 int task_count); 61 int task_count);
61 62
62 const std::vector<TaskEvent>& GetTaskEvents() const; 63 const std::vector<TaskEvent>& GetTaskEvents() const;
63 64
65 void WaitForCountTasksToComplete(int count);
akalin 2013/02/26 00:12:23 There's a bit of an ambiguity here -- do you mean
michaeln 2013/02/27 00:57:12 Done.
66
64 private: 67 private:
65 friend class RefCountedThreadSafe<SequencedTaskTracker>; 68 friend class RefCountedThreadSafe<SequencedTaskTracker>;
66 69
67 ~SequencedTaskTracker(); 70 ~SequencedTaskTracker();
68 71
69 // A task which runs |task|, recording the start and end events. 72 // A task which runs |task|, recording the start and end events.
70 void RunTask(const Closure& task, int task_i); 73 void RunTask(const Closure& task, int task_i);
71 74
72 // Records a post event for task |i|. The owner is expected to be holding 75 // Records a post event for task |i|. The owner is expected to be holding
73 // |lock_| (unlike |TaskStarted| and |TaskEnded|). 76 // |lock_| (unlike |TaskStarted| and |TaskEnded|).
74 void TaskPosted(int i); 77 void TaskPosted(int i);
75 78
76 // Records a start event for task |i|. 79 // Records a start event for task |i|.
77 void TaskStarted(int i); 80 void TaskStarted(int i);
78 81
79 // Records a end event for task |i|. 82 // Records a end event for task |i|.
80 void TaskEnded(int i); 83 void TaskEnded(int i);
81 84
82 // Protects events_ and next_post_i_. 85 // Protects events_, next_post_i_, task_end_count_ and task_end_cv_.
83 Lock lock_; 86 Lock lock_;
84 87
85 // The events as they occurred for each task (protected by lock_). 88 // The events as they occurred for each task (protected by lock_).
86 std::vector<TaskEvent> events_; 89 std::vector<TaskEvent> events_;
87 90
88 // The ordinal to be used for the next task-posting task (protected by 91 // The ordinal to be used for the next task-posting task (protected by
89 // lock_). 92 // lock_).
90 int next_post_i_; 93 int next_post_i_;
91 94
95 // The number of task ends we've received.
akalin 2013/02/26 00:12:23 task ends -> task end events
michaeln 2013/02/27 00:57:12 Done.
96 int task_end_count_;
97 ConditionVariable task_end_cv_;
98
92 DISALLOW_COPY_AND_ASSIGN(SequencedTaskTracker); 99 DISALLOW_COPY_AND_ASSIGN(SequencedTaskTracker);
93 }; 100 };
94 101
95 void PrintTo(const TaskEvent& event, std::ostream* os); 102 void PrintTo(const TaskEvent& event, std::ostream* os);
96 103
97 // Checks the non-nestable task invariants for all tasks in |events|. 104 // Checks the non-nestable task invariants for all tasks in |events|.
98 // 105 //
99 // The invariants are: 106 // The invariants are:
100 // 1) Events started and ended in the same order that they were posted. 107 // 1) Events started and ended in the same order that they were posted.
101 // 2) Events for an individual tasks occur in the order {POST, START, END}, 108 // 2) Events for an individual tasks occur in the order {POST, START, END},
102 // and there is only one instance of each event type for a task. 109 // and there is only one instance of each event type for a task.
103 // 3) The only events between a task's START and END events are the POSTs of 110 // 3) The only events between a task's START and END events are the POSTs of
104 // other tasks. I.e. tasks were run sequentially, not interleaved. 111 // other tasks. I.e. tasks were run sequentially, not interleaved.
105 ::testing::AssertionResult CheckNonNestableInvariants( 112 ::testing::AssertionResult CheckNonNestableInvariants(
106 const std::vector<TaskEvent>& events, 113 const std::vector<TaskEvent>& events,
107 int task_count); 114 int task_count);
108 115
109 } // namespace internal 116 } // namespace internal
110 117
111 template <typename TaskRunnerTestDelegate> 118 template <typename TaskRunnerTestDelegate>
112 class SequencedTaskRunnerTest : public testing::Test { 119 class SequencedTaskRunnerTest : public testing::Test {
113 protected: 120 protected:
114 SequencedTaskRunnerTest() 121 SequencedTaskRunnerTest()
115 : task_tracker_(new internal::SequencedTaskTracker()) {} 122 : task_tracker_(new internal::SequencedTaskTracker()) {}
116 123
117 const scoped_refptr<internal::SequencedTaskTracker> task_tracker_; 124 const scoped_refptr<internal::SequencedTaskTracker> task_tracker_;
118 TaskRunnerTestDelegate delegate_; 125 TaskRunnerTestDelegate delegate_;
119 }; 126 };
120 127
121 TYPED_TEST_CASE_P(SequencedTaskRunnerTest); 128 TYPED_TEST_CASE_P(SequencedTaskRunnerTest);
122 129
123 // This test posts N non-nestable tasks in sequence, and expects them to run 130 // This test posts N non-nestable tasks in sequence, and expects them to run
124 // in FIFO order, with no part of any two tasks' execution 131 // in FIFO order, with no part of any two tasks' execution
125 // overlapping. I.e. that each task starts only after the previously-posted 132 // overlapping. I.e. that each task starts only after the previously-posted
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 const scoped_refptr<SequencedTaskRunner> task_runner = 191 const scoped_refptr<SequencedTaskRunner> task_runner =
185 this->delegate_.GetTaskRunner(); 192 this->delegate_.GetTaskRunner();
186 193
187 for (int i = 0; i < kTaskCount; ++i) { 194 for (int i = 0; i < kTaskCount; ++i) {
188 this->task_tracker_->PostWrappedDelayedNonNestableTask( 195 this->task_tracker_->PostWrappedDelayedNonNestableTask(
189 task_runner, 196 task_runner,
190 Closure(), 197 Closure(),
191 TimeDelta::FromMilliseconds(kDelayIncrementMs * i)); 198 TimeDelta::FromMilliseconds(kDelayIncrementMs * i));
192 } 199 }
193 200
201 this->task_tracker_->WaitForCountTasksToComplete(kTaskCount);
194 this->delegate_.StopTaskRunner(); 202 this->delegate_.StopTaskRunner();
195 203
196 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 204 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
197 kTaskCount)); 205 kTaskCount));
198 } 206 }
199 207
200 // This test posts a fast, non-nestable task from within each of a number of 208 // This test posts a fast, non-nestable task from within each of a number of
201 // slow, non-nestable tasks and checks that they all run in the sequence they 209 // slow, non-nestable tasks and checks that they all run in the sequence they
202 // were posted in and that there is no execution overlap whatsoever. 210 // were posted in and that there is no execution overlap whatsoever.
203 TYPED_TEST_P(SequencedTaskRunnerTest, NonNestablePostFromNonNestableTask) { 211 TYPED_TEST_P(SequencedTaskRunnerTest, NonNestablePostFromNonNestableTask) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 const int kTaskCount = 1; 245 const int kTaskCount = 1;
238 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); 246 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
239 247
240 this->delegate_.StartTaskRunner(); 248 this->delegate_.StartTaskRunner();
241 const scoped_refptr<SequencedTaskRunner> task_runner = 249 const scoped_refptr<SequencedTaskRunner> task_runner =
242 this->delegate_.GetTaskRunner(); 250 this->delegate_.GetTaskRunner();
243 251
244 Time time_before_run = Time::Now(); 252 Time time_before_run = Time::Now();
245 this->task_tracker_->PostWrappedDelayedNonNestableTask( 253 this->task_tracker_->PostWrappedDelayedNonNestableTask(
246 task_runner, Closure(), kDelay); 254 task_runner, Closure(), kDelay);
255 this->task_tracker_->WaitForCountTasksToComplete(1);
akalin 2013/02/26 00:12:23 use kTaskCount here, too
michaeln 2013/02/27 00:57:12 Done.
247 this->delegate_.StopTaskRunner(); 256 this->delegate_.StopTaskRunner();
248 Time time_after_run = Time::Now(); 257 Time time_after_run = Time::Now();
249 258
250 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 259 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
251 kTaskCount)); 260 kTaskCount));
252 EXPECT_LE(kDelay, time_after_run - time_before_run); 261 EXPECT_LE(kDelay, time_after_run - time_before_run);
253 } 262 }
254 263
255 // This test posts two tasks with the same delay, and checks that the tasks are 264 // This test posts two tasks with the same delay, and checks that the tasks are
256 // run in the order in which they were posted. 265 // run in the order in which they were posted.
(...skipping 14 matching lines...) Expand all
271 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); 280 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
272 281
273 this->delegate_.StartTaskRunner(); 282 this->delegate_.StartTaskRunner();
274 const scoped_refptr<SequencedTaskRunner> task_runner = 283 const scoped_refptr<SequencedTaskRunner> task_runner =
275 this->delegate_.GetTaskRunner(); 284 this->delegate_.GetTaskRunner();
276 285
277 this->task_tracker_->PostWrappedDelayedNonNestableTask( 286 this->task_tracker_->PostWrappedDelayedNonNestableTask(
278 task_runner, Closure(), kDelay); 287 task_runner, Closure(), kDelay);
279 this->task_tracker_->PostWrappedDelayedNonNestableTask( 288 this->task_tracker_->PostWrappedDelayedNonNestableTask(
280 task_runner, Closure(), kDelay); 289 task_runner, Closure(), kDelay);
290 this->task_tracker_->WaitForCountTasksToComplete(kTaskCount);
281 this->delegate_.StopTaskRunner(); 291 this->delegate_.StopTaskRunner();
282 292
283 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 293 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
284 kTaskCount)); 294 kTaskCount));
285 } 295 }
286 296
287 // This test posts a normal task and a delayed task, and checks that the 297 // This test posts a normal task and a delayed task, and checks that the
288 // delayed task runs after the normal task even if the normal task takes 298 // delayed task runs after the normal task even if the normal task takes
289 // a long time to run. 299 // a long time to run.
290 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterLongTask) { 300 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterLongTask) {
291 // TODO(akalin): Remove this check (http://crbug.com/149144). 301 // TODO(akalin): Remove this check (http://crbug.com/149144).
292 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { 302 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
293 DLOG(INFO) << "This SequencedTaskRunner doesn't handle " 303 DLOG(INFO) << "This SequencedTaskRunner doesn't handle "
294 "non-zero delays; skipping"; 304 "non-zero delays; skipping";
295 return; 305 return;
296 } 306 }
297 307
298 const int kTaskCount = 2; 308 const int kTaskCount = 2;
299 309
300 this->delegate_.StartTaskRunner(); 310 this->delegate_.StartTaskRunner();
301 const scoped_refptr<SequencedTaskRunner> task_runner = 311 const scoped_refptr<SequencedTaskRunner> task_runner =
302 this->delegate_.GetTaskRunner(); 312 this->delegate_.GetTaskRunner();
303 313
304 this->task_tracker_->PostWrappedNonNestableTask( 314 this->task_tracker_->PostWrappedNonNestableTask(
305 task_runner, base::Bind(&PlatformThread::Sleep, 315 task_runner, base::Bind(&PlatformThread::Sleep,
306 TimeDelta::FromMilliseconds(50))); 316 TimeDelta::FromMilliseconds(50)));
307 this->task_tracker_->PostWrappedDelayedNonNestableTask( 317 this->task_tracker_->PostWrappedDelayedNonNestableTask(
308 task_runner, Closure(), TimeDelta::FromMilliseconds(10)); 318 task_runner, Closure(), TimeDelta::FromMilliseconds(10));
319 this->task_tracker_->WaitForCountTasksToComplete(kTaskCount);
309 this->delegate_.StopTaskRunner(); 320 this->delegate_.StopTaskRunner();
310 321
311 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 322 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
312 kTaskCount)); 323 kTaskCount));
313 } 324 }
314 325
315 // Test that a pile of normal tasks and a delayed task run in the 326 // Test that a pile of normal tasks and a delayed task run in the
316 // time-to-run order. 327 // time-to-run order.
317 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterManyLongTasks) { 328 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterManyLongTasks) {
318 // TODO(akalin): Remove this check (http://crbug.com/149144). 329 // TODO(akalin): Remove this check (http://crbug.com/149144).
319 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { 330 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
320 DLOG(INFO) << "This SequencedTaskRunner doesn't handle " 331 DLOG(INFO) << "This SequencedTaskRunner doesn't handle "
321 "non-zero delays; skipping"; 332 "non-zero delays; skipping";
322 return; 333 return;
323 } 334 }
324 335
325 const int kTaskCount = 11; 336 const int kTaskCount = 11;
326 337
327 this->delegate_.StartTaskRunner(); 338 this->delegate_.StartTaskRunner();
328 const scoped_refptr<SequencedTaskRunner> task_runner = 339 const scoped_refptr<SequencedTaskRunner> task_runner =
329 this->delegate_.GetTaskRunner(); 340 this->delegate_.GetTaskRunner();
330 341
331 for (int i = 0; i < kTaskCount - 1; i++) { 342 for (int i = 0; i < kTaskCount - 1; i++) {
332 this->task_tracker_->PostWrappedNonNestableTask( 343 this->task_tracker_->PostWrappedNonNestableTask(
333 task_runner, base::Bind(&PlatformThread::Sleep, 344 task_runner, base::Bind(&PlatformThread::Sleep,
334 TimeDelta::FromMilliseconds(50))); 345 TimeDelta::FromMilliseconds(50)));
335 } 346 }
336 this->task_tracker_->PostWrappedDelayedNonNestableTask( 347 this->task_tracker_->PostWrappedDelayedNonNestableTask(
337 task_runner, Closure(), TimeDelta::FromMilliseconds(10)); 348 task_runner, Closure(), TimeDelta::FromMilliseconds(10));
349 this->task_tracker_->WaitForCountTasksToComplete(kTaskCount);
338 this->delegate_.StopTaskRunner(); 350 this->delegate_.StopTaskRunner();
339 351
340 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 352 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
341 kTaskCount)); 353 kTaskCount));
342 } 354 }
343 355
344 356
345 // TODO(francoisk777@gmail.com) Add a test, similiar to the above, which runs 357 // TODO(francoisk777@gmail.com) Add a test, similiar to the above, which runs
346 // some tasked nestedly (which should be implemented in the test 358 // some tasked nestedly (which should be implemented in the test
347 // delegate). Also add, to the the test delegate, a predicate which checks 359 // delegate). Also add, to the the test delegate, a predicate which checks
348 // whether the implementation supports nested tasks. 360 // whether the implementation supports nested tasks.
349 // 361 //
350 362
351 REGISTER_TYPED_TEST_CASE_P(SequencedTaskRunnerTest, 363 REGISTER_TYPED_TEST_CASE_P(SequencedTaskRunnerTest,
352 SequentialNonNestable, 364 SequentialNonNestable,
353 SequentialNestable, 365 SequentialNestable,
354 SequentialDelayedNonNestable, 366 SequentialDelayedNonNestable,
355 NonNestablePostFromNonNestableTask, 367 NonNestablePostFromNonNestableTask,
356 DelayedTaskBasic, 368 DelayedTaskBasic,
357 DelayedTasksSameDelay, 369 DelayedTasksSameDelay,
358 DelayedTaskAfterLongTask, 370 DelayedTaskAfterLongTask,
359 DelayedTaskAfterManyLongTasks); 371 DelayedTaskAfterManyLongTasks);
360 372
361 } // namespace base 373 } // namespace base
362 374
363 #endif // BASE_TASK_RUNNER_TEST_TEMPLATE_H_ 375 #endif // BASE_TASK_RUNNER_TEST_TEMPLATE_H_
OLDNEW
« no previous file with comments | « no previous file | base/test/sequenced_task_runner_test_template.cc » ('j') | base/test/task_runner_test_template.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698