#ifndef BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_
#define BASE_TEST_TASK_RUNNER_TEST_TEMPLATE_H_
#include <cstddef>
#include <map>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_runner.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace test {
class TaskTracker : public RefCountedThreadSafe<TaskTracker> {
public:
TaskTracker();
TaskTracker(const TaskTracker&) = delete;
TaskTracker& operator=(const TaskTracker&) = delete;
RepeatingClosure WrapTask(RepeatingClosure task, int i);
std::map<int, int> GetTaskRunCounts() const;
void WaitForCompletedTasks(int count);
private:
friend class RefCountedThreadSafe<TaskTracker>;
~TaskTracker();
void RunTask(RepeatingClosure task, int i);
mutable Lock lock_;
std::map<int, int> task_run_counts_;
int task_runs_;
ConditionVariable task_runs_cv_;
};
}
template <typename TaskRunnerTestDelegate>
class TaskRunnerTest : public testing::Test {
protected:
TaskRunnerTest() : task_tracker_(base::MakeRefCounted<test::TaskTracker>()) {}
const scoped_refptr<test::TaskTracker> task_tracker_;
TaskRunnerTestDelegate delegate_;
};
TYPED_TEST_SUITE_P(TaskRunnerTest);
TYPED_TEST_P(TaskRunnerTest, Basic) {
std::map<int, int> expected_task_run_counts;
this->delegate_.StartTaskRunner();
scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner();
for (int i = 0; i < 20; ++i) {
RepeatingClosure ith_task =
this->task_tracker_->WrapTask(RepeatingClosure(), i);
for (int j = 0; j < i + 1; ++j) {
task_runner->PostTask(FROM_HERE, ith_task);
++expected_task_run_counts[i];
}
}
this->delegate_.StopTaskRunner();
EXPECT_EQ(expected_task_run_counts,
this->task_tracker_->GetTaskRunCounts());
}
TYPED_TEST_P(TaskRunnerTest, Delayed) {
std::map<int, int> expected_task_run_counts;
int expected_total_tasks = 0;
this->delegate_.StartTaskRunner();
scoped_refptr<TaskRunner> task_runner = this->delegate_.GetTaskRunner();
for (int i = 0; i < 20; ++i) {
RepeatingClosure ith_task =
this->task_tracker_->WrapTask(RepeatingClosure(), i);
for (int j = 0; j < i + 1; ++j) {
task_runner->PostDelayedTask(FROM_HERE, ith_task, base::Milliseconds(j));
++expected_task_run_counts[i];
++expected_total_tasks;
}
}
this->task_tracker_->WaitForCompletedTasks(expected_total_tasks);
this->delegate_.StopTaskRunner();
EXPECT_EQ(expected_task_run_counts,
this->task_tracker_->GetTaskRunCounts());
}
REGISTER_TYPED_TEST_SUITE_P(TaskRunnerTest, Basic, Delayed);
}
#endif