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

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, 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/test/sequenced_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 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 // Returns after the tracker observes a total of |count| task completions.
66 void WaitForCompletedTasks(int count);
67
64 private: 68 private:
65 friend class RefCountedThreadSafe<SequencedTaskTracker>; 69 friend class RefCountedThreadSafe<SequencedTaskTracker>;
66 70
67 ~SequencedTaskTracker(); 71 ~SequencedTaskTracker();
68 72
69 // A task which runs |task|, recording the start and end events. 73 // A task which runs |task|, recording the start and end events.
70 void RunTask(const Closure& task, int task_i); 74 void RunTask(const Closure& task, int task_i);
71 75
72 // Records a post event for task |i|. The owner is expected to be holding 76 // Records a post event for task |i|. The owner is expected to be holding
73 // |lock_| (unlike |TaskStarted| and |TaskEnded|). 77 // |lock_| (unlike |TaskStarted| and |TaskEnded|).
74 void TaskPosted(int i); 78 void TaskPosted(int i);
75 79
76 // Records a start event for task |i|. 80 // Records a start event for task |i|.
77 void TaskStarted(int i); 81 void TaskStarted(int i);
78 82
79 // Records a end event for task |i|. 83 // Records a end event for task |i|.
80 void TaskEnded(int i); 84 void TaskEnded(int i);
81 85
82 // Protects events_ and next_post_i_. 86 // Protects events_, next_post_i_, task_end_count_ and task_end_cv_.
83 Lock lock_; 87 Lock lock_;
84 88
85 // The events as they occurred for each task (protected by lock_). 89 // The events as they occurred for each task (protected by lock_).
86 std::vector<TaskEvent> events_; 90 std::vector<TaskEvent> events_;
87 91
88 // The ordinal to be used for the next task-posting task (protected by 92 // The ordinal to be used for the next task-posting task (protected by
89 // lock_). 93 // lock_).
90 int next_post_i_; 94 int next_post_i_;
91 95
96 // The number of task end events we've received.
97 int task_end_count_;
98 ConditionVariable task_end_cv_;
99
92 DISALLOW_COPY_AND_ASSIGN(SequencedTaskTracker); 100 DISALLOW_COPY_AND_ASSIGN(SequencedTaskTracker);
93 }; 101 };
94 102
95 void PrintTo(const TaskEvent& event, std::ostream* os); 103 void PrintTo(const TaskEvent& event, std::ostream* os);
96 104
97 // Checks the non-nestable task invariants for all tasks in |events|. 105 // Checks the non-nestable task invariants for all tasks in |events|.
98 // 106 //
99 // The invariants are: 107 // The invariants are:
100 // 1) Events started and ended in the same order that they were posted. 108 // 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}, 109 // 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. 110 // 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 111 // 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. 112 // other tasks. I.e. tasks were run sequentially, not interleaved.
105 ::testing::AssertionResult CheckNonNestableInvariants( 113 ::testing::AssertionResult CheckNonNestableInvariants(
106 const std::vector<TaskEvent>& events, 114 const std::vector<TaskEvent>& events,
107 int task_count); 115 int task_count);
108 116
109 } // namespace internal 117 } // namespace internal
110 118
111 template <typename TaskRunnerTestDelegate> 119 template <typename TaskRunnerTestDelegate>
112 class SequencedTaskRunnerTest : public testing::Test { 120 class SequencedTaskRunnerTest : public testing::Test {
113 protected: 121 protected:
114 SequencedTaskRunnerTest() 122 SequencedTaskRunnerTest()
115 : task_tracker_(new internal::SequencedTaskTracker()) {} 123 : task_tracker_(new internal::SequencedTaskTracker()) {}
116 124
117 const scoped_refptr<internal::SequencedTaskTracker> task_tracker_; 125 const scoped_refptr<internal::SequencedTaskTracker> task_tracker_;
118 TaskRunnerTestDelegate delegate_; 126 TaskRunnerTestDelegate delegate_;
119 }; 127 };
120 128
121 TYPED_TEST_CASE_P(SequencedTaskRunnerTest); 129 TYPED_TEST_CASE_P(SequencedTaskRunnerTest);
122 130
123 // This test posts N non-nestable tasks in sequence, and expects them to run 131 // 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 132 // in FIFO order, with no part of any two tasks' execution
125 // overlapping. I.e. that each task starts only after the previously-posted 133 // 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 = 192 const scoped_refptr<SequencedTaskRunner> task_runner =
185 this->delegate_.GetTaskRunner(); 193 this->delegate_.GetTaskRunner();
186 194
187 for (int i = 0; i < kTaskCount; ++i) { 195 for (int i = 0; i < kTaskCount; ++i) {
188 this->task_tracker_->PostWrappedDelayedNonNestableTask( 196 this->task_tracker_->PostWrappedDelayedNonNestableTask(
189 task_runner, 197 task_runner,
190 Closure(), 198 Closure(),
191 TimeDelta::FromMilliseconds(kDelayIncrementMs * i)); 199 TimeDelta::FromMilliseconds(kDelayIncrementMs * i));
192 } 200 }
193 201
202 this->task_tracker_->WaitForCompletedTasks(kTaskCount);
194 this->delegate_.StopTaskRunner(); 203 this->delegate_.StopTaskRunner();
195 204
196 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 205 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
197 kTaskCount)); 206 kTaskCount));
198 } 207 }
199 208
200 // This test posts a fast, non-nestable task from within each of a number of 209 // 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 210 // 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. 211 // were posted in and that there is no execution overlap whatsoever.
203 TYPED_TEST_P(SequencedTaskRunnerTest, NonNestablePostFromNonNestableTask) { 212 TYPED_TEST_P(SequencedTaskRunnerTest, NonNestablePostFromNonNestableTask) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 const int kTaskCount = 1; 246 const int kTaskCount = 1;
238 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); 247 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
239 248
240 this->delegate_.StartTaskRunner(); 249 this->delegate_.StartTaskRunner();
241 const scoped_refptr<SequencedTaskRunner> task_runner = 250 const scoped_refptr<SequencedTaskRunner> task_runner =
242 this->delegate_.GetTaskRunner(); 251 this->delegate_.GetTaskRunner();
243 252
244 Time time_before_run = Time::Now(); 253 Time time_before_run = Time::Now();
245 this->task_tracker_->PostWrappedDelayedNonNestableTask( 254 this->task_tracker_->PostWrappedDelayedNonNestableTask(
246 task_runner, Closure(), kDelay); 255 task_runner, Closure(), kDelay);
256 this->task_tracker_->WaitForCompletedTasks(kTaskCount);
247 this->delegate_.StopTaskRunner(); 257 this->delegate_.StopTaskRunner();
248 Time time_after_run = Time::Now(); 258 Time time_after_run = Time::Now();
249 259
250 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 260 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
251 kTaskCount)); 261 kTaskCount));
252 EXPECT_LE(kDelay, time_after_run - time_before_run); 262 EXPECT_LE(kDelay, time_after_run - time_before_run);
253 } 263 }
254 264
255 // This test posts two tasks with the same delay, and checks that the tasks are 265 // 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. 266 // run in the order in which they were posted.
(...skipping 14 matching lines...) Expand all
271 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); 281 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
272 282
273 this->delegate_.StartTaskRunner(); 283 this->delegate_.StartTaskRunner();
274 const scoped_refptr<SequencedTaskRunner> task_runner = 284 const scoped_refptr<SequencedTaskRunner> task_runner =
275 this->delegate_.GetTaskRunner(); 285 this->delegate_.GetTaskRunner();
276 286
277 this->task_tracker_->PostWrappedDelayedNonNestableTask( 287 this->task_tracker_->PostWrappedDelayedNonNestableTask(
278 task_runner, Closure(), kDelay); 288 task_runner, Closure(), kDelay);
279 this->task_tracker_->PostWrappedDelayedNonNestableTask( 289 this->task_tracker_->PostWrappedDelayedNonNestableTask(
280 task_runner, Closure(), kDelay); 290 task_runner, Closure(), kDelay);
291 this->task_tracker_->WaitForCompletedTasks(kTaskCount);
281 this->delegate_.StopTaskRunner(); 292 this->delegate_.StopTaskRunner();
282 293
283 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 294 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
284 kTaskCount)); 295 kTaskCount));
285 } 296 }
286 297
287 // This test posts a normal task and a delayed task, and checks that the 298 // 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 299 // delayed task runs after the normal task even if the normal task takes
289 // a long time to run. 300 // a long time to run.
290 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterLongTask) { 301 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterLongTask) {
291 // TODO(akalin): Remove this check (http://crbug.com/149144). 302 // TODO(akalin): Remove this check (http://crbug.com/149144).
292 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { 303 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
293 DLOG(INFO) << "This SequencedTaskRunner doesn't handle " 304 DLOG(INFO) << "This SequencedTaskRunner doesn't handle "
294 "non-zero delays; skipping"; 305 "non-zero delays; skipping";
295 return; 306 return;
296 } 307 }
297 308
298 const int kTaskCount = 2; 309 const int kTaskCount = 2;
299 310
300 this->delegate_.StartTaskRunner(); 311 this->delegate_.StartTaskRunner();
301 const scoped_refptr<SequencedTaskRunner> task_runner = 312 const scoped_refptr<SequencedTaskRunner> task_runner =
302 this->delegate_.GetTaskRunner(); 313 this->delegate_.GetTaskRunner();
303 314
304 this->task_tracker_->PostWrappedNonNestableTask( 315 this->task_tracker_->PostWrappedNonNestableTask(
305 task_runner, base::Bind(&PlatformThread::Sleep, 316 task_runner, base::Bind(&PlatformThread::Sleep,
306 TimeDelta::FromMilliseconds(50))); 317 TimeDelta::FromMilliseconds(50)));
307 this->task_tracker_->PostWrappedDelayedNonNestableTask( 318 this->task_tracker_->PostWrappedDelayedNonNestableTask(
308 task_runner, Closure(), TimeDelta::FromMilliseconds(10)); 319 task_runner, Closure(), TimeDelta::FromMilliseconds(10));
320 this->task_tracker_->WaitForCompletedTasks(kTaskCount);
309 this->delegate_.StopTaskRunner(); 321 this->delegate_.StopTaskRunner();
310 322
311 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 323 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
312 kTaskCount)); 324 kTaskCount));
313 } 325 }
314 326
315 // Test that a pile of normal tasks and a delayed task run in the 327 // Test that a pile of normal tasks and a delayed task run in the
316 // time-to-run order. 328 // time-to-run order.
317 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterManyLongTasks) { 329 TYPED_TEST_P(SequencedTaskRunnerTest, DelayedTaskAfterManyLongTasks) {
318 // TODO(akalin): Remove this check (http://crbug.com/149144). 330 // TODO(akalin): Remove this check (http://crbug.com/149144).
319 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { 331 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) {
320 DLOG(INFO) << "This SequencedTaskRunner doesn't handle " 332 DLOG(INFO) << "This SequencedTaskRunner doesn't handle "
321 "non-zero delays; skipping"; 333 "non-zero delays; skipping";
322 return; 334 return;
323 } 335 }
324 336
325 const int kTaskCount = 11; 337 const int kTaskCount = 11;
326 338
327 this->delegate_.StartTaskRunner(); 339 this->delegate_.StartTaskRunner();
328 const scoped_refptr<SequencedTaskRunner> task_runner = 340 const scoped_refptr<SequencedTaskRunner> task_runner =
329 this->delegate_.GetTaskRunner(); 341 this->delegate_.GetTaskRunner();
330 342
331 for (int i = 0; i < kTaskCount - 1; i++) { 343 for (int i = 0; i < kTaskCount - 1; i++) {
332 this->task_tracker_->PostWrappedNonNestableTask( 344 this->task_tracker_->PostWrappedNonNestableTask(
333 task_runner, base::Bind(&PlatformThread::Sleep, 345 task_runner, base::Bind(&PlatformThread::Sleep,
334 TimeDelta::FromMilliseconds(50))); 346 TimeDelta::FromMilliseconds(50)));
335 } 347 }
336 this->task_tracker_->PostWrappedDelayedNonNestableTask( 348 this->task_tracker_->PostWrappedDelayedNonNestableTask(
337 task_runner, Closure(), TimeDelta::FromMilliseconds(10)); 349 task_runner, Closure(), TimeDelta::FromMilliseconds(10));
350 this->task_tracker_->WaitForCompletedTasks(kTaskCount);
338 this->delegate_.StopTaskRunner(); 351 this->delegate_.StopTaskRunner();
339 352
340 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(), 353 EXPECT_TRUE(CheckNonNestableInvariants(this->task_tracker_->GetTaskEvents(),
341 kTaskCount)); 354 kTaskCount));
342 } 355 }
343 356
344 357
345 // TODO(francoisk777@gmail.com) Add a test, similiar to the above, which runs 358 // TODO(francoisk777@gmail.com) Add a test, similiar to the above, which runs
346 // some tasked nestedly (which should be implemented in the test 359 // some tasked nestedly (which should be implemented in the test
347 // delegate). Also add, to the the test delegate, a predicate which checks 360 // delegate). Also add, to the the test delegate, a predicate which checks
348 // whether the implementation supports nested tasks. 361 // whether the implementation supports nested tasks.
349 // 362 //
350 363
351 REGISTER_TYPED_TEST_CASE_P(SequencedTaskRunnerTest, 364 REGISTER_TYPED_TEST_CASE_P(SequencedTaskRunnerTest,
352 SequentialNonNestable, 365 SequentialNonNestable,
353 SequentialNestable, 366 SequentialNestable,
354 SequentialDelayedNonNestable, 367 SequentialDelayedNonNestable,
355 NonNestablePostFromNonNestableTask, 368 NonNestablePostFromNonNestableTask,
356 DelayedTaskBasic, 369 DelayedTaskBasic,
357 DelayedTasksSameDelay, 370 DelayedTasksSameDelay,
358 DelayedTaskAfterLongTask, 371 DelayedTaskAfterLongTask,
359 DelayedTaskAfterManyLongTasks); 372 DelayedTaskAfterManyLongTasks);
360 373
361 } // namespace base 374 } // namespace base
362 375
363 #endif // BASE_TASK_RUNNER_TEST_TEMPLATE_H_ 376 #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') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698