Chromium Code Reviews| 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 file defines tests that implementations of TaskRunner should | 5 // This file defines tests that implementations of TaskRunner should |
| 6 // pass in order to be conformant, as well as test cases for optional behavior. | 6 // pass in order to be conformant, as well as test cases for optional behavior. |
| 7 // Here's how you use it to test your implementation. | 7 // Here's how you use it to test your 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 #include "base/single_thread_task_runner.h" | 65 #include "base/single_thread_task_runner.h" |
| 66 #include "base/synchronization/condition_variable.h" | 66 #include "base/synchronization/condition_variable.h" |
| 67 #include "base/synchronization/lock.h" | 67 #include "base/synchronization/lock.h" |
| 68 #include "base/task_runner.h" | 68 #include "base/task_runner.h" |
| 69 #include "base/threading/thread.h" | 69 #include "base/threading/thread.h" |
| 70 #include "base/tracked_objects.h" | 70 #include "base/tracked_objects.h" |
| 71 #include "testing/gtest/include/gtest/gtest.h" | 71 #include "testing/gtest/include/gtest/gtest.h" |
| 72 | 72 |
| 73 namespace base { | 73 namespace base { |
| 74 | 74 |
| 75 namespace internal { | 75 namespace testing { |
|
gab
2016/03/09 21:53:26
Missing rebase? Thought this change was made upstr
fdoray
2016/03/15 17:28:09
Yes, missing rebase. I will rebase everything afte
| |
| 76 | 76 |
| 77 // Utility class that keeps track of how many times particular tasks | 77 // Utility class that keeps track of how many times particular tasks |
| 78 // are run. | 78 // are run. |
| 79 class TaskTracker : public RefCountedThreadSafe<TaskTracker> { | 79 class TaskTracker : public RefCountedThreadSafe<TaskTracker> { |
| 80 public: | 80 public: |
| 81 TaskTracker(); | 81 TaskTracker(); |
| 82 | 82 |
| 83 // Returns a closure that runs the given task and increments the run | 83 // Returns a closure that runs the given task and increments the run |
| 84 // count of |i| by one. |task| may be null. It is guaranteed that | 84 // count of |i| by one. |task| may be null. It is guaranteed that |
| 85 // only one task wrapped by a given tracker will be run at a time. | 85 // only one task wrapped by a given tracker will be run at a time. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 98 void RunTask(const Closure& task, int i); | 98 void RunTask(const Closure& task, int i); |
| 99 | 99 |
| 100 mutable Lock lock_; | 100 mutable Lock lock_; |
| 101 std::map<int, int> task_run_counts_; | 101 std::map<int, int> task_run_counts_; |
| 102 int task_runs_; | 102 int task_runs_; |
| 103 ConditionVariable task_runs_cv_; | 103 ConditionVariable task_runs_cv_; |
| 104 | 104 |
| 105 DISALLOW_COPY_AND_ASSIGN(TaskTracker); | 105 DISALLOW_COPY_AND_ASSIGN(TaskTracker); |
| 106 }; | 106 }; |
| 107 | 107 |
| 108 } // namespace internal | 108 } // namespace testing |
| 109 | 109 |
| 110 template <typename TaskRunnerTestDelegate> | 110 template <typename TaskRunnerTestDelegate> |
| 111 class TaskRunnerTest : public testing::Test { | 111 class TaskRunnerTest : public ::testing::Test { |
| 112 protected: | 112 protected: |
| 113 TaskRunnerTest() : task_tracker_(new internal::TaskTracker()) {} | 113 TaskRunnerTest() : task_tracker_(new testing::TaskTracker()) {} |
| 114 | 114 |
| 115 const scoped_refptr<internal::TaskTracker> task_tracker_; | 115 const scoped_refptr<testing::TaskTracker> task_tracker_; |
| 116 TaskRunnerTestDelegate delegate_; | 116 TaskRunnerTestDelegate delegate_; |
| 117 }; | 117 }; |
| 118 | 118 |
| 119 TYPED_TEST_CASE_P(TaskRunnerTest); | 119 TYPED_TEST_CASE_P(TaskRunnerTest); |
| 120 | 120 |
| 121 // We can't really test much, since TaskRunner provides very few | 121 // We can't really test much, since TaskRunner provides very few |
| 122 // guarantees. | 122 // guarantees. |
| 123 | 123 |
| 124 // Post a bunch of tasks to the task runner. They should all | 124 // Post a bunch of tasks to the task runner. They should all |
| 125 // complete. | 125 // complete. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 this->delegate_.StopTaskRunner(); | 164 this->delegate_.StopTaskRunner(); |
| 165 | 165 |
| 166 EXPECT_EQ(expected_task_run_counts, | 166 EXPECT_EQ(expected_task_run_counts, |
| 167 this->task_tracker_->GetTaskRunCounts()); | 167 this->task_tracker_->GetTaskRunCounts()); |
| 168 } | 168 } |
| 169 | 169 |
| 170 // The TaskRunnerTest test case verifies behaviour that is expected from a | 170 // The TaskRunnerTest test case verifies behaviour that is expected from a |
| 171 // task runner in order to be conformant. | 171 // task runner in order to be conformant. |
| 172 REGISTER_TYPED_TEST_CASE_P(TaskRunnerTest, Basic, Delayed); | 172 REGISTER_TYPED_TEST_CASE_P(TaskRunnerTest, Basic, Delayed); |
| 173 | 173 |
| 174 namespace internal { | 174 namespace testing { |
| 175 | 175 |
| 176 // Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to | 176 // Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to |
| 177 // equal |expected_value|. | 177 // equal |expected_value|. |
| 178 void ExpectRunsTasksOnCurrentThread( | 178 void ExpectRunsTasksOnCurrentThread( |
| 179 bool expected_value, | 179 bool expected_value, |
| 180 const scoped_refptr<TaskRunner>& task_runner); | 180 const scoped_refptr<TaskRunner>& task_runner); |
| 181 | 181 |
| 182 } // namespace internal | 182 } // namespace testing |
| 183 | 183 |
| 184 template <typename TaskRunnerTestDelegate> | 184 template <typename TaskRunnerTestDelegate> |
| 185 class TaskRunnerAffinityTest : public TaskRunnerTest<TaskRunnerTestDelegate> {}; | 185 class TaskRunnerAffinityTest : public TaskRunnerTest<TaskRunnerTestDelegate> {}; |
| 186 | 186 |
| 187 TYPED_TEST_CASE_P(TaskRunnerAffinityTest); | 187 TYPED_TEST_CASE_P(TaskRunnerAffinityTest); |
| 188 | 188 |
| 189 // Post a bunch of tasks to the task runner as well as to a separate | 189 // Post a bunch of tasks to the task runner as well as to a separate |
| 190 // thread, each checking the value of RunsTasksOnCurrentThread(), | 190 // thread, each checking the value of RunsTasksOnCurrentThread(), |
| 191 // which should return true for the tasks posted on the task runner | 191 // which should return true for the tasks posted on the task runner |
| 192 // and false for the tasks posted on the separate thread. | 192 // and false for the tasks posted on the separate thread. |
| 193 TYPED_TEST_P(TaskRunnerAffinityTest, RunsTasksOnCurrentThread) { | 193 TYPED_TEST_P(TaskRunnerAffinityTest, RunsTasksOnCurrentThread) { |
| 194 std::map<int, int> expected_task_run_counts; | 194 std::map<int, int> expected_task_run_counts; |
| 195 | 195 |
| 196 Thread thread("Non-task-runner thread"); | 196 Thread thread("Non-task-runner thread"); |
| 197 ASSERT_TRUE(thread.Start()); | 197 ASSERT_TRUE(thread.Start()); |
| 198 this->delegate_.StartTaskRunner(); | 198 this->delegate_.StartTaskRunner(); |
| 199 | 199 |
| 200 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); | 200 scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); |
| 201 // Post each ith task i+1 times on the task runner and i+1 times on | 201 // Post each ith task i+1 times on the task runner and i+1 times on |
| 202 // the non-task-runner thread. | 202 // the non-task-runner thread. |
| 203 for (int i = 0; i < 20; ++i) { | 203 for (int i = 0; i < 20; ++i) { |
| 204 const Closure& ith_task_runner_task = | 204 const Closure& ith_task_runner_task = this->task_tracker_->WrapTask( |
| 205 this->task_tracker_->WrapTask( | 205 Bind(&testing::ExpectRunsTasksOnCurrentThread, true, task_runner), i); |
| 206 Bind(&internal::ExpectRunsTasksOnCurrentThread, | 206 const Closure& ith_non_task_runner_task = this->task_tracker_->WrapTask( |
| 207 true, task_runner), | 207 Bind(&testing::ExpectRunsTasksOnCurrentThread, false, task_runner), i); |
| 208 i); | |
| 209 const Closure& ith_non_task_runner_task = | |
| 210 this->task_tracker_->WrapTask( | |
| 211 Bind(&internal::ExpectRunsTasksOnCurrentThread, | |
| 212 false, task_runner), | |
| 213 i); | |
| 214 for (int j = 0; j < i + 1; ++j) { | 208 for (int j = 0; j < i + 1; ++j) { |
| 215 task_runner->PostTask(FROM_HERE, ith_task_runner_task); | 209 task_runner->PostTask(FROM_HERE, ith_task_runner_task); |
| 216 thread.task_runner()->PostTask(FROM_HERE, ith_non_task_runner_task); | 210 thread.task_runner()->PostTask(FROM_HERE, ith_non_task_runner_task); |
| 217 expected_task_run_counts[i] += 2; | 211 expected_task_run_counts[i] += 2; |
| 218 } | 212 } |
| 219 } | 213 } |
| 220 | 214 |
| 221 this->delegate_.StopTaskRunner(); | 215 this->delegate_.StopTaskRunner(); |
| 222 thread.Stop(); | 216 thread.Stop(); |
| 223 | 217 |
| 224 EXPECT_EQ(expected_task_run_counts, | 218 EXPECT_EQ(expected_task_run_counts, |
| 225 this->task_tracker_->GetTaskRunCounts()); | 219 this->task_tracker_->GetTaskRunCounts()); |
| 226 } | 220 } |
| 227 | 221 |
| 228 // TaskRunnerAffinityTest tests that the TaskRunner implementation | 222 // TaskRunnerAffinityTest tests that the TaskRunner implementation |
| 229 // can determine if tasks will never be run on a specific thread. | 223 // can determine if tasks will never be run on a specific thread. |
| 230 REGISTER_TYPED_TEST_CASE_P(TaskRunnerAffinityTest, RunsTasksOnCurrentThread); | 224 REGISTER_TYPED_TEST_CASE_P(TaskRunnerAffinityTest, RunsTasksOnCurrentThread); |
| 231 | 225 |
| 232 } // namespace base | 226 } // namespace base |
| 233 | 227 |
| 234 #endif // BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ | 228 #endif // BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_ |
| OLD | NEW |