Index: base/task_runner_test_template.h |
diff --git a/base/task_runner_test_template.h b/base/task_runner_test_template.h |
index 012fa88058387395500c561dbd97d68d1cafa2fc..de347d68d7286b6019710156f6916bfdd2e44793 100644 |
--- a/base/task_runner_test_template.h |
+++ b/base/task_runner_test_template.h |
@@ -57,20 +57,28 @@ |
#include "base/basictypes.h" |
#include "base/bind.h" |
+#include "base/callback.h" |
#include "base/memory/ref_counted.h" |
#include "base/synchronization/lock.h" |
#include "base/task_runner.h" |
+#include "base/threading/thread.h" |
#include "base/tracked_objects.h" |
#include "testing/gtest/include/gtest/gtest.h" |
namespace base { |
-// Utility class used in the tests below. |
+namespace internal { |
+ |
+// Utility class that keeps track of how many times particular tasks |
+// are run. |
class TaskTracker : public RefCountedThreadSafe<TaskTracker> { |
public: |
TaskTracker(); |
- void RunTask(int i); |
+ // Returns a closure that runs the given task and increments the run |
+ // count of |i| by one. |task| may be null. It is guaranteed that |
+ // only one task wrapped by a given tracker will be run at a time. |
+ Closure WrapTask(const Closure& task, int i); |
std::map<int, int> GetTaskRunCounts() const; |
@@ -79,18 +87,22 @@ class TaskTracker : public RefCountedThreadSafe<TaskTracker> { |
~TaskTracker(); |
+ void RunTask(const Closure& task, int i); |
+ |
mutable Lock task_run_counts_lock_; |
std::map<int, int> task_run_counts_; |
DISALLOW_COPY_AND_ASSIGN(TaskTracker); |
}; |
+} // namespace internal |
+ |
template <typename TaskRunnerTestDelegate> |
class TaskRunnerTest : public testing::Test { |
protected: |
- TaskRunnerTest() : task_tracker_(new TaskTracker()) {} |
+ TaskRunnerTest() : task_tracker_(new internal::TaskTracker()) {} |
- const scoped_refptr<TaskTracker> task_tracker_; |
+ const scoped_refptr<internal::TaskTracker> task_tracker_; |
TaskRunnerTestDelegate delegate_; |
}; |
@@ -108,9 +120,9 @@ TYPED_TEST_P(TaskRunnerTest, Basic) { |
scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); |
// Post each ith task i+1 times. |
for (int i = 0; i < 20; ++i) { |
- Closure task = Bind(&TaskTracker::RunTask, this->task_tracker_, i); |
+ const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i); |
for (int j = 0; j < i + 1; ++j) { |
- task_runner->PostTask(FROM_HERE, task); |
+ task_runner->PostTask(FROM_HERE, ith_task); |
++expected_task_run_counts[i]; |
} |
} |
@@ -134,9 +146,9 @@ TYPED_TEST_P(TaskRunnerTest, Delayed) { |
scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); |
// Post each ith task i+1 times with delays from 0-i. |
for (int i = 0; i < 20; ++i) { |
- Closure task = Bind(&TaskTracker::RunTask, this->task_tracker_, i); |
+ const Closure& ith_task = this->task_tracker_->WrapTask(Closure(), i); |
for (int j = 0; j < i + 1; ++j) { |
- task_runner->PostDelayedTask(FROM_HERE, task, j); |
+ task_runner->PostDelayedTask(FROM_HERE, ith_task, j); |
++expected_task_run_counts[i]; |
} |
} |
@@ -146,11 +158,57 @@ TYPED_TEST_P(TaskRunnerTest, Delayed) { |
this->task_tracker_->GetTaskRunCounts()); |
} |
-// TODO(akalin): Add test to verify RunsTaskOnCurrentThread() returns |
-// true for tasks runs on the TaskRunner and returns false on a |
-// separate PlatformThread. |
+namespace internal { |
+ |
+// Calls RunsTasksOnCurrentThread() on |task_runner| and expects it to |
+// equal |expected_value|. |
+void ExpectRunsTasksOnCurrentThread( |
+ bool expected_value, |
+ const scoped_refptr<TaskRunner>& task_runner); |
+ |
+} // namespace internal |
+ |
+// Post a bunch of tasks to the task runner as well as to a separate |
+// thread, each checking the value of RunsTasksOnCurrentThread(), |
+// which should return true for the tasks posted on the task runner |
+// and false for the tasks posted on the separate thread. |
+TYPED_TEST_P(TaskRunnerTest, RunsTasksOnCurrentThread) { |
+ std::map<int, int> expected_task_run_counts; |
+ |
+ Thread thread("Non-task-runner thread"); |
+ ASSERT_TRUE(thread.Start()); |
+ this->delegate_.StartTaskRunner(); |
+ |
+ scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner(); |
+ // Post each ith task i+1 times on the task runner and i+1 times on |
+ // the non-task-runner thread. |
+ for (int i = 0; i < 20; ++i) { |
+ const Closure& ith_task_runner_task = |
+ this->task_tracker_->WrapTask( |
+ Bind(&internal::ExpectRunsTasksOnCurrentThread, |
+ true, task_runner), |
+ i); |
+ const Closure& ith_non_task_runner_task = |
+ this->task_tracker_->WrapTask( |
+ Bind(&internal::ExpectRunsTasksOnCurrentThread, |
+ false, task_runner), |
+ i); |
+ for (int j = 0; j < i + 1; ++j) { |
+ task_runner->PostTask(FROM_HERE, ith_task_runner_task); |
+ thread.message_loop()->PostTask(FROM_HERE, ith_non_task_runner_task); |
+ expected_task_run_counts[i] += 2; |
+ } |
+ } |
+ |
+ this->delegate_.StopTaskRunner(); |
+ thread.Stop(); |
+ |
+ EXPECT_EQ(expected_task_run_counts, |
+ this->task_tracker_->GetTaskRunCounts()); |
+} |
-REGISTER_TYPED_TEST_CASE_P(TaskRunnerTest, Basic, Delayed); |
+REGISTER_TYPED_TEST_CASE_P( |
+ TaskRunnerTest, Basic, Delayed, RunsTasksOnCurrentThread); |
} // namespace base |