Chromium Code Reviews| Index: base/task_scheduler/task_tracker_unittest.cc |
| diff --git a/base/task_scheduler/task_tracker_unittest.cc b/base/task_scheduler/task_tracker_unittest.cc |
| index 58f47b8153458816889e15c31961b0e5aa9732cd..81b5503196a508a23c9f9c181ceb8a0964007a4b 100644 |
| --- a/base/task_scheduler/task_tracker_unittest.cc |
| +++ b/base/task_scheduler/task_tracker_unittest.cc |
| @@ -14,10 +14,12 @@ |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/memory/ref_counted.h" |
| +#include "base/sequence_token.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/task_scheduler/scheduler_lock.h" |
| +#include "base/task_scheduler/sequence.h" |
| #include "base/task_scheduler/task.h" |
| #include "base/task_scheduler/task_traits.h" |
| #include "base/task_scheduler/test_utils.h" |
| @@ -36,6 +38,12 @@ namespace { |
| constexpr size_t kLoadTestNumIterations = 100; |
| +scoped_refptr<Sequence> CreateSequenceWithTask(std::unique_ptr<Task> task) { |
| + scoped_refptr<Sequence> sequence(new Sequence); |
| + sequence->PushTask(std::move(task)); |
| + return sequence; |
| +} |
| + |
| // Calls TaskTracker::Shutdown() asynchronously. |
| class ThreadCallingShutdown : public SimpleThread { |
| public: |
| @@ -69,12 +77,12 @@ class ThreadPostingAndRunningTask : public SimpleThread { |
| }; |
| ThreadPostingAndRunningTask(TaskTracker* tracker, |
| - const Task* task, |
| + scoped_refptr<Sequence> sequence, |
| Action action, |
| bool expect_post_succeeds) |
| : SimpleThread("ThreadPostingAndRunningTask"), |
| tracker_(tracker), |
| - task_(task), |
| + sequence_(std::move(sequence)), |
| action_(action), |
| expect_post_succeeds_(expect_post_succeeds) {} |
| @@ -82,17 +90,17 @@ class ThreadPostingAndRunningTask : public SimpleThread { |
| void Run() override { |
| bool post_succeeded = true; |
| if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { |
| - post_succeeded = tracker_->WillPostTask(task_); |
| + post_succeeded = tracker_->WillPostTask(sequence_->PeekTask()); |
| EXPECT_EQ(expect_post_succeeds_, post_succeeded); |
| } |
| if (post_succeeded && |
| (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { |
| - tracker_->RunTask(task_); |
| + tracker_->RunNextTaskInSequence(sequence_.get()); |
| } |
| } |
| TaskTracker* const tracker_; |
| - const Task* const task_; |
| + const scoped_refptr<Sequence> sequence_; |
| const Action action_; |
| const bool expect_post_succeeds_; |
| @@ -197,7 +205,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { |
| // Run the task. |
| EXPECT_EQ(0U, NumTasksExecuted()); |
| - tracker_.RunTask(task.get()); |
| + tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
| EXPECT_EQ(1U, NumTasksExecuted()); |
| // Shutdown() shouldn't block. |
| @@ -217,8 +225,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { |
| // Run the task asynchronouly. |
| ThreadPostingAndRunningTask thread_running_task( |
| - &tracker_, blocked_task.get(), ThreadPostingAndRunningTask::Action::RUN, |
| - false); |
| + &tracker_, CreateSequenceWithTask(std::move(blocked_task)), |
| + ThreadPostingAndRunningTask::Action::RUN, false); |
| thread_running_task.Start(); |
| // Initiate shutdown while the task is running. |
| @@ -259,13 +267,14 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunDuringShutdown) { |
| // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it |
| // should be discarded. |
| EXPECT_EQ(0U, NumTasksExecuted()); |
| - tracker_.RunTask(task.get()); |
| + tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
| EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 1U : 0U, |
| NumTasksExecuted()); |
| VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. |
| - tracker_.RunTask(block_shutdown_task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
| EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
| NumTasksExecuted()); |
| WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| @@ -284,7 +293,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
| VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| // Run the task to unblock shutdown. |
| - tracker_.RunTask(task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(task)).get()); |
| EXPECT_EQ(1U, NumTasksExecuted()); |
| WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| @@ -295,7 +305,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
| WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| // The task shouldn't be allowed to run after shutdown. |
| - tracker_.RunTask(task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(task)).get()); |
| EXPECT_EQ(0U, NumTasksExecuted()); |
| } |
| } |
| @@ -318,7 +329,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
| // Run the BLOCK_SHUTDOWN task. |
| EXPECT_EQ(0U, NumTasksExecuted()); |
| - tracker_.RunTask(task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(task)).get()); |
| EXPECT_EQ(1U, NumTasksExecuted()); |
| } else { |
| // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. |
| @@ -330,7 +342,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
| // Unblock shutdown by running |block_shutdown_task|. |
| VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| - tracker_.RunTask(block_shutdown_task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
| EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
| NumTasksExecuted()); |
| WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| @@ -356,9 +369,10 @@ TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
| (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); |
| TaskTracker tracker; |
| - Task task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), |
| - TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
| - EXPECT_TRUE(tracker.WillPostTask(&task)); |
| + std::unique_ptr<Task> task( |
| + new Task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), |
| + TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
| + EXPECT_TRUE(tracker.WillPostTask(task.get())); |
| // Set the singleton allowed bit to the opposite of what it is expected to be |
| // when |tracker| runs |task| to verify that |tracker| actually sets the |
| @@ -367,23 +381,31 @@ TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
| // Running the task should fail iff the task isn't allowed to use singletons. |
| if (can_use_singletons) { |
| - tracker.RunTask(&task); |
| + tracker.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(task)).get()); |
| } else { |
| - EXPECT_DCHECK_DEATH({ tracker.RunTask(&task); }, ""); |
| + EXPECT_DCHECK_DEATH( |
| + { |
| + tracker.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(task)).get()); |
| + }, |
| + ""); |
| } |
| } |
| -static void RunTaskRunnerHandleVerificationTask(TaskTracker* tracker, |
| - const Task* verify_task) { |
| +static void RunTaskRunnerHandleVerificationTask( |
| + TaskTracker* tracker, |
| + std::unique_ptr<Task> verify_task) { |
| // Pretend |verify_task| is posted to respect TaskTracker's contract. |
| - EXPECT_TRUE(tracker->WillPostTask(verify_task)); |
| + EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); |
| // Confirm that the test conditions are right (no TaskRunnerHandles set |
| // already). |
| EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
| EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
| - tracker->RunTask(verify_task); |
| + tracker->RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(verify_task)).get()); |
| // TaskRunnerHandle state is reset outside of task's scope. |
| EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
| @@ -402,7 +424,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { |
| new Task(FROM_HERE, Bind(&VerifyNoTaskRunnerHandle), |
| TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
| - RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
| + RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
| } |
| static void VerifySequencedTaskRunnerHandle( |
| @@ -425,7 +447,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, |
| TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
| verify_task->sequenced_task_runner_ref = test_task_runner; |
| - RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
| + RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
| } |
| static void VerifyThreadTaskRunnerHandle( |
| @@ -450,7 +472,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, |
| TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
| verify_task->single_thread_task_runner_ref = test_task_runner; |
| - RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
| + RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
| } |
| INSTANTIATE_TEST_CASE_P( |
| @@ -466,27 +488,46 @@ INSTANTIATE_TEST_CASE_P( |
| TaskSchedulerTaskTrackerTest, |
| ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| +namespace { |
|
robliao
2016/07/25 17:57:21
Nit: Padding one line break after "namespace {" an
fdoray
2016/07/26 20:44:56
Done.
|
| +void ExpectSequenceToken(SequenceToken sequence_token) { |
| + EXPECT_EQ(sequence_token, SequenceToken::GetCurrent()); |
| +} |
| +} // namespace |
| + |
| +// Verify that SequenceToken::GetCurrent() returns the Sequence's token when a |
| +// Task runs. |
| +TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { |
| + scoped_refptr<Sequence> sequence(new Sequence); |
| + sequence->PushTask(WrapUnique( |
| + new Task(FROM_HERE, Bind(&ExpectSequenceToken, sequence->token()), |
| + TaskTraits(), TimeDelta()))); |
| + tracker_.WillPostTask(sequence->PeekTask()); |
| + |
| + EXPECT_FALSE(SequenceToken::GetCurrent().IsValid()); |
| + tracker_.RunNextTaskInSequence(sequence.get()); |
| + EXPECT_FALSE(SequenceToken::GetCurrent().IsValid()); |
| +} |
| + |
| TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
| // Post and run tasks asynchronously. |
| - std::vector<std::unique_ptr<Task>> tasks; |
| std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
| threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
| threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
| threads.back()->Start(); |
| } |
| @@ -504,25 +545,28 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
| TEST_F(TaskSchedulerTaskTrackerTest, |
| LoadWillPostBeforeShutdownAndRunDuringShutdown) { |
| // Post tasks asynchronously. |
| - std::vector<std::unique_ptr<Task>> tasks; |
| + std::vector<scoped_refptr<Sequence>> sequences; |
| std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; |
| for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| + sequences.push_back(CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN))); |
| post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, sequences.back(), |
| ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
| post_threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| + sequences.push_back(CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); |
| post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, sequences.back(), |
| ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
| post_threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| + sequences.push_back(CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN))); |
| post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, sequences.back(), |
| ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
| post_threads.back()->Start(); |
| } |
| @@ -536,10 +580,9 @@ TEST_F(TaskSchedulerTaskTrackerTest, |
| // Run tasks asynchronously. |
| std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
| - for (const auto& task : tasks) { |
| + for (const auto& sequence : sequences) { |
| run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, |
| - false))); |
| + &tracker_, sequence, ThreadPostingAndRunningTask::Action::RUN, false))); |
| run_threads.back()->Start(); |
| } |
| @@ -563,25 +606,24 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
| CallShutdownAsync(); |
| // Post and run tasks asynchronously. |
| - std::vector<std::unique_ptr<Task>> tasks; |
| std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
| threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
| threads.back()->Start(); |
| - tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
| - &tracker_, tasks.back().get(), |
| + &tracker_, CreateSequenceWithTask( |
| + CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
| ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
| threads.back()->Start(); |
| } |
| @@ -596,7 +638,8 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
| VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| // Unblock shutdown by running |block_shutdown_task|. |
| - tracker_.RunTask(block_shutdown_task.get()); |
| + tracker_.RunNextTaskInSequence( |
| + CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
| EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
| WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| } |