Index: base/task_scheduler/scheduler_worker_thread_unittest.cc |
diff --git a/base/task_scheduler/scheduler_worker_thread_unittest.cc b/base/task_scheduler/scheduler_worker_thread_unittest.cc |
index 541d1bc0800f315eea99b72ac7b60d7b141d6b2a..8c4cb8212671c511ffa57e4ab163ca581e88c296 100644 |
--- a/base/task_scheduler/scheduler_worker_thread_unittest.cc |
+++ b/base/task_scheduler/scheduler_worker_thread_unittest.cc |
@@ -14,6 +14,8 @@ |
#include "base/macros.h" |
#include "base/memory/ptr_util.h" |
#include "base/synchronization/condition_variable.h" |
+#include "base/task_scheduler/delayed_task_manager.h" |
+#include "base/task_scheduler/priority_queue.h" |
#include "base/task_scheduler/scheduler_lock.h" |
#include "base/task_scheduler/sequence.h" |
#include "base/task_scheduler/task.h" |
@@ -24,19 +26,20 @@ namespace base { |
namespace internal { |
namespace { |
-const size_t kNumSequencesPerTest = 150; |
- |
// The test parameter is the number of Tasks per Sequence returned by GetWork(). |
-class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
- public SchedulerWorkerThread::Delegate { |
+class TaskSchedulerWorkerThreadDelegateWorkTest |
+ : public testing::TestWithParam<size_t>, |
+ public SchedulerWorkerThread::Delegate { |
protected: |
- TaskSchedulerWorkerThreadTest() |
- : main_entry_called_(true, false), |
+ TaskSchedulerWorkerThreadDelegateWorkTest() |
+ : delayed_task_manager_(Bind(&DoNothing)), |
+ main_entry_called_(true, false), |
num_get_work_cv_(lock_.CreateConditionVariable()) {} |
void SetUp() override { |
worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread( |
- ThreadPriority::NORMAL, this, &task_tracker_); |
+ ThreadPriority::NORMAL, this, &task_tracker_, &delayed_task_manager_, |
+ &dummy_priority_queue_); |
ASSERT_TRUE(worker_thread_); |
main_entry_called_.Wait(); |
} |
@@ -80,6 +83,8 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
return enqueued_sequences_; |
} |
+ const size_t kNumSequencesPerTest = 150; |
gab
2016/04/18 18:04:02
s/const/constexpr/ (see chromium-dev about new C++
fdoray
2016/04/18 19:04:50
Done.
|
+ |
std::unique_ptr<SchedulerWorkerThread> worker_thread_; |
private: |
@@ -92,8 +97,9 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
main_entry_called_.Signal(); |
} |
- scoped_refptr<Sequence> GetWork( |
- SchedulerWorkerThread* worker_thread) override { |
+ scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread, |
+ PriorityQueue* single_threaded_priority_queue, |
+ bool* is_single_threaded_sequence) override { |
EXPECT_EQ(worker_thread_.get(), worker_thread); |
{ |
@@ -116,8 +122,9 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
scoped_refptr<Sequence> sequence(new Sequence); |
for (size_t i = 0; i < TasksPerSequence(); ++i) { |
std::unique_ptr<Task> task(new Task( |
- FROM_HERE, Bind(&TaskSchedulerWorkerThreadTest::RunTaskCallback, |
- Unretained(this)), |
+ FROM_HERE, |
+ Bind(&TaskSchedulerWorkerThreadDelegateWorkTest::RunTaskCallback, |
+ Unretained(this)), |
TaskTraits())); |
EXPECT_TRUE(task_tracker_.WillPostTask(task.get())); |
sequence->PushTask(std::move(task)); |
@@ -159,6 +166,8 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
} |
TaskTracker task_tracker_; |
+ DelayedTaskManager delayed_task_manager_; |
+ PriorityQueue dummy_priority_queue_; |
// Synchronizes access to all members below. |
mutable SchedulerLock lock_; |
@@ -188,12 +197,12 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, |
// Number of times that RunTaskCallback() has been called. |
size_t num_run_tasks_ = 0; |
- DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest); |
+ DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadDelegateWorkTest); |
}; |
// Verify that when GetWork() continuously returns Sequences, all Tasks in these |
// Sequences run successfully. The test wakes up the SchedulerWorkerThread once. |
-TEST_P(TaskSchedulerWorkerThreadTest, ContinuousWork) { |
+TEST_P(TaskSchedulerWorkerThreadDelegateWorkTest, ContinuousWork) { |
// Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to |
// return nullptr. |
SetNumSequencesToCreate(kNumSequencesPerTest); |
@@ -223,7 +232,7 @@ TEST_P(TaskSchedulerWorkerThreadTest, ContinuousWork) { |
// Verify that when GetWork() alternates between returning a Sequence and |
// returning nullptr, all Tasks in the returned Sequences run successfully. The |
// test wakes up the SchedulerWorkerThread once for each Sequence. |
-TEST_P(TaskSchedulerWorkerThreadTest, IntermittentWork) { |
+TEST_P(TaskSchedulerWorkerThreadDelegateWorkTest, IntermittentWork) { |
for (size_t i = 0; i < kNumSequencesPerTest; ++i) { |
// Set GetWork() to return 1 Sequence before starting to return |
// nullptr. |
@@ -253,12 +262,128 @@ TEST_P(TaskSchedulerWorkerThreadTest, IntermittentWork) { |
} |
INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, |
- TaskSchedulerWorkerThreadTest, |
+ TaskSchedulerWorkerThreadDelegateWorkTest, |
::testing::Values(1)); |
INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, |
- TaskSchedulerWorkerThreadTest, |
+ TaskSchedulerWorkerThreadDelegateWorkTest, |
::testing::Values(2)); |
+class TaskSchedulerWorkerThreadSingleThreadedWorkTest |
+ : public testing::Test, |
+ public SchedulerWorkerThread::Delegate { |
+ protected: |
+ TaskSchedulerWorkerThreadSingleThreadedWorkTest() |
+ : delayed_task_manager_(Bind(&DoNothing)), |
+ num_run_tasks_cv_(lock_.CreateConditionVariable()) {} |
+ |
+ void SetUp() override { |
+ worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread( |
+ ThreadPriority::NORMAL, this, &task_tracker_, &delayed_task_manager_, |
+ &dummy_priority_queue_); |
+ ASSERT_TRUE(worker_thread_); |
+ } |
+ |
+ void TearDown() override { worker_thread_->JoinForTesting(); } |
+ |
+ void PostTestTask(scoped_refptr<TaskRunner> task_runner) { |
+ Closure closure; |
+ { |
+ AutoSchedulerLock auto_lock(lock_); |
+ closure = Bind( |
+ &TaskSchedulerWorkerThreadSingleThreadedWorkTest::RunTaskCallback, |
+ Unretained(this), num_posted_tasks_++, task_runner); |
gab
2016/04/18 18:04:02
Only need to lock to get index from |num_posted_ta
fdoray
2016/04/18 19:04:50
Done.
|
+ } |
+ task_runner->PostTask(FROM_HERE, closure); |
+ } |
+ |
+ void WaitForAllTasksToRun() { |
+ AutoSchedulerLock auto_lock(lock_); |
+ while (num_run_tasks_ < num_posted_tasks_) |
+ num_run_tasks_cv_->Wait(); |
+ } |
+ |
+ const size_t kNumTasksPerTest = 150; |
+ |
+ std::unique_ptr<SchedulerWorkerThread> worker_thread_; |
+ |
+ private: |
+ // SchedulerWorkerThread::Delegate: |
+ void OnMainEntry() override {} |
+ |
+ scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread, |
+ PriorityQueue* single_threaded_priority_queue, |
+ bool* is_single_threaded_sequence) override { |
+ EXPECT_EQ(worker_thread_.get(), worker_thread); |
+ |
+ // Return a Sequence from |single_threaded_priority_queue| or nullptr if it |
+ // is empty. |
+ auto transaction = single_threaded_priority_queue->BeginTransaction(); |
+ auto sequence = transaction->Peek().sequence; |
+ if (!sequence) |
+ return nullptr; |
+ *is_single_threaded_sequence = true; |
+ transaction->Pop(); |
+ return sequence; |
+ } |
+ |
+ void EnqueueSequence(scoped_refptr<Sequence> sequence) override { |
+ ADD_FAILURE() << "EnqueueSequence shouldn't be called in a test that only " |
+ "posts single-threaded Tasks."; |
+ } |
+ |
+ void RunTaskCallback(size_t index, scoped_refptr<TaskRunner> task_runner) { |
+ AutoSchedulerLock auto_lock(lock_); |
+ |
+ EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); |
+ |
+ // Verify that tasks run in posting order. |
+ EXPECT_EQ(num_run_tasks_, index); |
+ |
+ // Verify that we don't run more tasks than posted. |
+ ++num_run_tasks_; |
+ EXPECT_LE(num_run_tasks_, num_posted_tasks_); |
+ |
+ num_run_tasks_cv_->Signal(); |
+ } |
+ |
+ TaskTracker task_tracker_; |
+ DelayedTaskManager delayed_task_manager_; |
+ PriorityQueue dummy_priority_queue_; |
+ |
+ // Synchronizes access to all members below. |
+ mutable SchedulerLock lock_; |
+ |
+ // Number of tasks posted by PostTestTask(). |
+ size_t num_posted_tasks_ = 0; |
+ |
+ // Number of times that RunTaskCallback() has been called. |
+ size_t num_run_tasks_ = 0; |
+ |
+ // Condition variable signaled when |num_run_tasks_| is incremented. |
+ std::unique_ptr<ConditionVariable> num_run_tasks_cv_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadSingleThreadedWorkTest); |
+}; |
+ |
+TEST_F(TaskSchedulerWorkerThreadSingleThreadedWorkTest, ContinuousWork) { |
+ auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(TaskTraits()); |
+ EXPECT_FALSE(task_runner->RunsTasksOnCurrentThread()); |
+ |
+ for (size_t i = 0; i < kNumTasksPerTest; ++i) |
+ PostTestTask(task_runner); |
+ WaitForAllTasksToRun(); |
+} |
+ |
+TEST_F(TaskSchedulerWorkerThreadSingleThreadedWorkTest, IntermittentWork) { |
+ auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(TaskTraits()); |
+ EXPECT_FALSE(task_runner->RunsTasksOnCurrentThread()); |
+ |
+ for (size_t i = 0; i < kNumTasksPerTest; ++i) { |
+ PostTestTask(task_runner); |
+ WaitForAllTasksToRun(); |
+ } |
+} |
+ |
} // namespace |
} // namespace internal |
} // namespace base |