| OLD | NEW |
| 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 |
| 11 // like this: | 11 // like this: |
| 12 // | 12 // |
| 13 // class MyTaskRunnerTestDelegate { | 13 // class MyTaskRunnerTestDelegate { |
| 14 // public: | 14 // public: |
| 15 // // Tasks posted to the task runner after this and before | 15 // // Tasks posted to the task runner after this and before |
| 16 // // StopTaskRunner() is called is called should run successfully. | 16 // // StopTaskRunner() is called is called should run successfully. |
| 17 // void StartTaskRunner() { | 17 // void StartTaskRunner() { |
| 18 // ... | 18 // ... |
| 19 // } | 19 // } |
| 20 // | 20 // |
| 21 // // Should return the task runner implementation. Only called | 21 // // Should return the task runner implementation. Only called |
| 22 // // after StartTaskRunner and before StopTaskRunner. | 22 // // after StartTaskRunner and before StopTaskRunner. |
| 23 // scoped_refptr<MyTaskRunner> GetTaskRunner() { | 23 // scoped_refptr<MyTaskRunner> GetTaskRunner() { |
| 24 // ... | 24 // ... |
| 25 // } | 25 // } |
| 26 // | 26 // |
| 27 // // Stop the task runner and make sure all tasks posted before | 27 // // Stop the task runner and make sure all tasks posted before |
| 28 // // this is called are run. | 28 // // this is called are run. Caveat: delayed tasks are not run, |
| 29 // they're simply deleted. |
| 29 // void StopTaskRunner() { | 30 // void StopTaskRunner() { |
| 30 // ... | 31 // ... |
| 31 // } | 32 // } |
| 32 // | 33 // |
| 33 // // Returns whether or not the task runner obeys non-zero delays. | 34 // // Returns whether or not the task runner obeys non-zero delays. |
| 34 // bool TaskRunnerHandlesNonZeroDelays() const { | 35 // bool TaskRunnerHandlesNonZeroDelays() const { |
| 35 // return true; | 36 // return true; |
| 36 // } | 37 // } |
| 37 // }; | 38 // }; |
| 38 // | 39 // |
| (...skipping 12 matching lines...) Expand all Loading... |
| 51 #ifndef BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ | 52 #ifndef BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ |
| 52 #define BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ | 53 #define BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ |
| 53 | 54 |
| 54 #include <cstddef> | 55 #include <cstddef> |
| 55 #include <map> | 56 #include <map> |
| 56 | 57 |
| 57 #include "base/basictypes.h" | 58 #include "base/basictypes.h" |
| 58 #include "base/bind.h" | 59 #include "base/bind.h" |
| 59 #include "base/callback.h" | 60 #include "base/callback.h" |
| 60 #include "base/memory/ref_counted.h" | 61 #include "base/memory/ref_counted.h" |
| 62 #include "base/synchronization/condition_variable.h" |
| 61 #include "base/synchronization/lock.h" | 63 #include "base/synchronization/lock.h" |
| 62 #include "base/task_runner.h" | 64 #include "base/task_runner.h" |
| 63 #include "base/threading/thread.h" | 65 #include "base/threading/thread.h" |
| 64 #include "base/tracked_objects.h" | 66 #include "base/tracked_objects.h" |
| 65 #include "testing/gtest/include/gtest/gtest.h" | 67 #include "testing/gtest/include/gtest/gtest.h" |
| 66 | 68 |
| 67 namespace base { | 69 namespace base { |
| 68 | 70 |
| 69 namespace internal { | 71 namespace internal { |
| 70 | 72 |
| 71 // Utility class that keeps track of how many times particular tasks | 73 // Utility class that keeps track of how many times particular tasks |
| 72 // are run. | 74 // are run. |
| 73 class TaskTracker : public RefCountedThreadSafe<TaskTracker> { | 75 class TaskTracker : public RefCountedThreadSafe<TaskTracker> { |
| 74 public: | 76 public: |
| 75 TaskTracker(); | 77 TaskTracker(); |
| 76 | 78 |
| 77 // Returns a closure that runs the given task and increments the run | 79 // Returns a closure that runs the given task and increments the run |
| 78 // count of |i| by one. |task| may be null. It is guaranteed that | 80 // count of |i| by one. |task| may be null. It is guaranteed that |
| 79 // only one task wrapped by a given tracker will be run at a time. | 81 // only one task wrapped by a given tracker will be run at a time. |
| 80 Closure WrapTask(const Closure& task, int i); | 82 Closure WrapTask(const Closure& task, int i); |
| 81 | 83 |
| 82 std::map<int, int> GetTaskRunCounts() const; | 84 std::map<int, int> GetTaskRunCounts() const; |
| 83 | 85 |
| 86 // Returns after the tracker observes a total of |count| task completions. |
| 87 void WaitForCompletedTasks(int count); |
| 88 |
| 84 private: | 89 private: |
| 85 friend class RefCountedThreadSafe<TaskTracker>; | 90 friend class RefCountedThreadSafe<TaskTracker>; |
| 86 | 91 |
| 87 ~TaskTracker(); | 92 ~TaskTracker(); |
| 88 | 93 |
| 89 void RunTask(const Closure& task, int i); | 94 void RunTask(const Closure& task, int i); |
| 90 | 95 |
| 91 mutable Lock task_run_counts_lock_; | 96 mutable Lock lock_; |
| 92 std::map<int, int> task_run_counts_; | 97 std::map<int, int> task_run_counts_; |
| 98 int task_runs_; |
| 99 ConditionVariable task_runs_cv_; |
| 93 | 100 |
| 94 DISALLOW_COPY_AND_ASSIGN(TaskTracker); | 101 DISALLOW_COPY_AND_ASSIGN(TaskTracker); |
| 95 }; | 102 }; |
| 96 | 103 |
| 97 } // namespace internal | 104 } // namespace internal |
| 98 | 105 |
| 99 template <typename TaskRunnerTestDelegate> | 106 template <typename TaskRunnerTestDelegate> |
| 100 class TaskRunnerTest : public testing::Test { | 107 class TaskRunnerTest : public testing::Test { |
| 101 protected: | 108 protected: |
| 102 TaskRunnerTest() : task_tracker_(new internal::TaskTracker()) {} | 109 TaskRunnerTest() : task_tracker_(new internal::TaskTracker()) {} |
| (...skipping 30 matching lines...) Expand all Loading... |
| 133 | 140 |
| 134 // Post a bunch of delayed tasks to the task runner. They should all | 141 // Post a bunch of delayed tasks to the task runner. They should all |
| 135 // complete. | 142 // complete. |
| 136 TYPED_TEST_P(TaskRunnerTest, Delayed) { | 143 TYPED_TEST_P(TaskRunnerTest, Delayed) { |
| 137 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { | 144 if (!this->delegate_.TaskRunnerHandlesNonZeroDelays()) { |
| 138 DLOG(INFO) << "This TaskRunner doesn't handle non-zero delays; skipping"; | 145 DLOG(INFO) << "This TaskRunner doesn't handle non-zero delays; skipping"; |
| 139 return; | 146 return; |
| 140 } | 147 } |
| 141 | 148 |
| 142 std::map<int, int> expected_task_run_counts; | 149 std::map<int, int> expected_task_run_counts; |
| 150 int expected_total_tasks = 0; |
| 143 | 151 |
| 144 this->delegate_.StartTaskRunner(); | 152 this->delegate_.StartTaskRunner(); |
| 145 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); | 153 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); |
| 146 // Post each ith task i+1 times with delays from 0-i. | 154 // Post each ith task i+1 times with delays from 0-i. |
| 147 for (int i = 0; i < 20; ++i) { | 155 for (int i = 0; i < 20; ++i) { |
| 148 const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i); | 156 const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i); |
| 149 for (int j = 0; j < i + 1; ++j) { | 157 for (int j = 0; j < i + 1; ++j) { |
| 150 task_runner->PostDelayedTask( | 158 task_runner->PostDelayedTask( |
| 151 FROM_HERE, ith_task, base::TimeDelta::FromMilliseconds(j)); | 159 FROM_HERE, ith_task, base::TimeDelta::FromMilliseconds(j)); |
| 152 ++expected_task_run_counts[i]; | 160 ++expected_task_run_counts[i]; |
| 161 ++expected_total_tasks; |
| 153 } | 162 } |
| 154 } | 163 } |
| 164 this->task_tracker_->WaitForCompletedTasks(expected_total_tasks); |
| 155 this->delegate_.StopTaskRunner(); | 165 this->delegate_.StopTaskRunner(); |
| 156 | 166 |
| 157 EXPECT_EQ(expected_task_run_counts, | 167 EXPECT_EQ(expected_task_run_counts, |
| 158 this->task_tracker_->GetTaskRunCounts()); | 168 this->task_tracker_->GetTaskRunCounts()); |
| 159 } | 169 } |
| 160 | 170 |
| 161 namespace internal { | 171 namespace internal { |
| 162 | 172 |
| 163 // Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to | 173 // Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to |
| 164 // equal |expected_value|. | 174 // equal |expected_value|. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 EXPECT_EQ(expected_task_run_counts, | 216 EXPECT_EQ(expected_task_run_counts, |
| 207 this->task_tracker_->GetTaskRunCounts()); | 217 this->task_tracker_->GetTaskRunCounts()); |
| 208 } | 218 } |
| 209 | 219 |
| 210 REGISTER_TYPED_TEST_CASE_P( | 220 REGISTER_TYPED_TEST_CASE_P( |
| 211 TaskRunnerTest, Basic, Delayed, RunsTasksOnCurrentThread); | 221 TaskRunnerTest, Basic, Delayed, RunsTasksOnCurrentThread); |
| 212 | 222 |
| 213 } // namespace base | 223 } // namespace base |
| 214 | 224 |
| 215 #endif //#define BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ | 225 #endif //#define BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ |
| OLD | NEW |