| 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
|
|
|
|
|