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 | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..d72b4abfc0dc9509507f60757ac710d0abb96cf1 | 
| --- /dev/null | 
| +++ b/base/task_scheduler/task_tracker_unittest.cc | 
| @@ -0,0 +1,471 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "base/task_scheduler/task_tracker.h" | 
| + | 
| +#include <queue> | 
| + | 
| +#include "base/bind.h" | 
| +#include "base/macros.h" | 
| +#include "base/memory/scoped_ptr.h" | 
| +#include "base/synchronization/waitable_event.h" | 
| +#include "base/task_scheduler/task.h" | 
| +#include "base/task_scheduler/task_traits.h" | 
| +#include "base/threading/platform_thread.h" | 
| +#include "base/threading/simple_thread.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace base { | 
| +namespace internal { | 
| + | 
| +namespace { | 
| + | 
| +class ThreadCallingShutdown : public SimpleThread { | 
| + public: | 
| + explicit ThreadCallingShutdown(TaskTracker* tracker) | 
| + : SimpleThread("ThreadCallingShutdown"), | 
| + tracker_(tracker), | 
| + has_returned_(false) {} | 
| + | 
| + // Returns true once the call to Shutdown() has returned. | 
| + bool has_returned() const { return has_returned_; } | 
| + | 
| + private: | 
| + void Run() override { | 
| + tracker_->Shutdown(); | 
| + has_returned_ = true; | 
| + } | 
| + | 
| + TaskTracker* const tracker_; | 
| + bool has_returned_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(ThreadCallingShutdown); | 
| +}; | 
| + | 
| +class TaskSchedulerTaskTrackerTest | 
| + : public testing::Test, | 
| + public ::testing::WithParamInterface<TaskShutdownBehavior> { | 
| 
 
gab
2016/03/09 21:53:25
You can use testing::TestWithParam<TaskShutdownBeh
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + public: | 
| + TaskSchedulerTaskTrackerTest() : num_tasks_executed_(0) {} | 
| 
 
gab
2016/03/09 21:53:25
Can initialize member inline now with C++11 :-)
(
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + | 
| + // Creates a task with |shutdown_behavior|. | 
| + scoped_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { | 
| + return make_scoped_ptr(new Task( | 
| + FROM_HERE, | 
| + Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), | 
| + TaskTraits().WithShutdownBehavior(shutdown_behavior))); | 
| + } | 
| + | 
| + // Tries to post |task| via |tracker_|. If |tracker_| approves the operation, | 
| + // |task| is added to |posted_tasks_|. | 
| + void PostTaskViaTracker(scoped_ptr<Task> task) { | 
| + tracker_.PostTask( | 
| + Bind(&TaskSchedulerTaskTrackerTest::PostTaskCallback, Unretained(this)), | 
| + std::move(task)); | 
| + } | 
| + | 
| + void RunNextPostedTaskViaTracker() { | 
| 
 
gab
2016/03/09 21:53:25
All methods but this one can move to "protected" I
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + tracker_.RunTask(posted_tasks_.front().get()); | 
| + posted_tasks_.pop(); | 
| + } | 
| + | 
| + // Calls tracker_->Shutdown() on a new thread. When this returns, the | 
| + // Shutdown() method has been entered on the new thread, but it hasn't | 
| + // necessarily returned. | 
| + void CallShutdownAsync() { | 
| + DCHECK(!thread_calling_shutdown_.get()); | 
| + thread_calling_shutdown_.reset(new ThreadCallingShutdown(&tracker_)); | 
| + thread_calling_shutdown_->Start(); | 
| + while (!tracker_.is_shutting_down_for_testing() && | 
| + !tracker_.shutdown_completed()) { | 
| + PlatformThread::YieldCurrentThread(); | 
| + } | 
| + } | 
| + | 
| + void JoinAndExpectShutdownAsyncHasReturned() { | 
| 
 
gab
2016/03/09 21:53:25
JoinAndExpectAsyncShutdownCompleted() ?
 
fdoray
2016/03/15 17:28:09
Done. Called it WaitForAsyncShutdownCompleted as y
 
 | 
| + DCHECK(thread_calling_shutdown_.get()); | 
| + thread_calling_shutdown_->Join(); | 
| + EXPECT_TRUE(thread_calling_shutdown_->has_returned()); | 
| + EXPECT_TRUE(tracker_.shutdown_completed()); | 
| + } | 
| + | 
| + void ExpectShutdownAsyncHasNotReturned() { | 
| 
 
gab
2016/03/09 21:53:25
VerifyAsyncShutdownInProgress()?
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + DCHECK(thread_calling_shutdown_.get()); | 
| + EXPECT_FALSE(thread_calling_shutdown_->has_returned()); | 
| 
 
gab
2016/03/09 21:53:25
Add EXPECT_TRUE(tracker_.is_shutting_down_for_test
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + EXPECT_FALSE(tracker_.shutdown_completed()); | 
| + } | 
| + | 
| + protected: | 
| + TaskTracker tracker_; | 
| + size_t num_tasks_executed_; | 
| + std::queue<scoped_ptr<Task>> posted_tasks_; | 
| + | 
| + private: | 
| + void PostTaskCallback(scoped_ptr<Task> task) { | 
| + posted_tasks_.push(std::move(task)); | 
| + } | 
| + | 
| + void RunTaskCallback() { ++num_tasks_executed_; } | 
| + | 
| + scoped_ptr<ThreadCallingShutdown> thread_calling_shutdown_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(TaskSchedulerTaskTrackerTest); | 
| +}; | 
| + | 
| +// A thread which calls | 
| +// TaskSchedulerTaskTrackerTest::RunNextPostedTaskViaTracker() asynchronously. | 
| +class ThreadRunningNextPostedTask : public SimpleThread { | 
| + public: | 
| + explicit ThreadRunningNextPostedTask(TaskSchedulerTaskTrackerTest* test) | 
| + : SimpleThread("ThreadRunningNextPostedTask"), test_(test) {} | 
| + | 
| + private: | 
| + void Run() override { test_->RunNextPostedTaskViaTracker(); } | 
| + | 
| + TaskSchedulerTaskTrackerTest* const test_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(ThreadRunningNextPostedTask); | 
| +}; | 
| + | 
| +} // namespace | 
| + | 
| +// This test is repeated for each TaskShutownBehavior. | 
| +TEST_P(TaskSchedulerTaskTrackerTest, PostAndRunBeforeShutdown) { | 
| 
 
robliao
2016/03/09 22:31:46
If the parametrized tests are like the ones here (
 
fdoray
2016/03/15 17:28:09
Every test is parameterized now.
 
 | 
| + scoped_ptr<Task> task_to_post(CreateTask(GetParam())); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + EXPECT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // Run the posted task. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + | 
| + // Shutdown() shouldn't block. | 
| + tracker_.Shutdown(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostAndRunLongTaskBeforeShutdown_ContinueOnShutdown) { | 
| + // Post a CONTINUE_ON_SHUTDOWN task that will block until |event| is signaled. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + WaitableEvent event(false, false); | 
| + PostTaskViaTracker(make_scoped_ptr( | 
| + new Task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), | 
| + TaskTraits().WithShutdownBehavior( | 
| + TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)))); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| 
 
gab
2016/03/09 21:53:25
Even better than verifying !empty() IMO here and e
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + | 
| + // Run the task asynchronouly. | 
| + ThreadRunningNextPostedTask thread(this); | 
| + thread.Start(); | 
| + | 
| + // Shutdown() shouldn't block. | 
| + tracker_.Shutdown(); | 
| + | 
| + // Unblock the task. | 
| + event.Signal(); | 
| + thread.Join(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostAndRunLongTaskBeforeShutdown_SkipOnShutdown) { | 
| + // Post a SKIP_ON_SHUTDOWN task that will block until |event| is signaled. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + WaitableEvent event(false, false); | 
| + PostTaskViaTracker(make_scoped_ptr( | 
| + new Task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), | 
| + TaskTraits().WithShutdownBehavior( | 
| + TaskShutdownBehavior::SKIP_ON_SHUTDOWN)))); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + | 
| + // Run the task asynchronouly. | 
| + ThreadRunningNextPostedTask thread(this); | 
| + thread.Start(); | 
| + | 
| + // Shutdown() should block until the task has completed its execution. | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Unblock the task. | 
| + event.Signal(); | 
| + thread.Join(); | 
| + | 
| + // Shutdown() should now return. | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostAndRunLongTaskBeforeShutdown_BlockShutdown) { | 
| + // Post a BLOCK_SHUTDOWN task that will block until |event| is signaled. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + WaitableEvent event(false, false); | 
| + PostTaskViaTracker(make_scoped_ptr( | 
| + new Task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), | 
| + TaskTraits().WithShutdownBehavior( | 
| + TaskShutdownBehavior::BLOCK_SHUTDOWN)))); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + | 
| + // Run the task asynchronouly. | 
| + ThreadRunningNextPostedTask thread(this); | 
| + thread.Start(); | 
| + | 
| + // Shutdown() should block until the task has completed its execution. | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Unblock the task. | 
| + event.Signal(); | 
| + thread.Join(); | 
| + | 
| + // Shutdown() should now return. | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| 
 
gab
2016/03/09 21:53:25
I'm surprised mixing TEST_F with TEST_P even works
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| 
 
gab
2016/03/09 21:53:25
Same thing as above for all remaining TEST_F's, tr
 
fdoray
2016/03/15 17:28:09
Done.
 
 | 
| + PostBeforeShutdownRunDuringShutdown_ContinueOnShutdown) { | 
| + scoped_ptr<Task> task_to_post( | 
| + CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + EXPECT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to run task posted at the beginning of this test. It should not work. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Unblock shutdown by running the BLOCK_SHUTDOWN task. | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostBeforeShutdownRunDuringShutdown_SkipOnShutdown) { | 
| + scoped_ptr<Task> task_to_post( | 
| + CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + EXPECT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to run task posted at the beginning of this test. It should not work. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Unblock shutdown by running the BLOCK_SHUTDOWN task. | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostBeforeShutdownRunDuringShutdown_BlockShutdown) { | 
| + scoped_ptr<Task> task_to_post( | 
| + CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + EXPECT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to run the first task posted in this test. It should run successfully. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(2U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostBeforeShutdownRunAfterShutdown_ContinueOnShutdown) { | 
| + scoped_ptr<Task> task_to_post( | 
| + CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + ASSERT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // This should return immediately. | 
| + tracker_.Shutdown(); | 
| + | 
| + // The task shouldn't be allowed to run. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostBeforeShutdownRunAfterShutdown_SkipOnShutdown) { | 
| + scoped_ptr<Task> task_to_post( | 
| + CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 
| + const Task* task_to_post_raw = task_to_post.get(); | 
| + | 
| + // Post the task. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(std::move(task_to_post)); | 
| + ASSERT_FALSE(posted_tasks_.empty()); | 
| + ASSERT_EQ(task_to_post_raw, posted_tasks_.front().get()); | 
| + | 
| + // This should return immediately. | 
| + tracker_.Shutdown(); | 
| + | 
| + // The task shouldn't be allowed to run. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| +} | 
| + | 
| +// It isn't possible to test running after shutdown a task that has been posted | 
| +// before shutdown because Shutdown() won't return until the task has been | 
| +// executed. | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, RunAfterShutdown_BlockShutdown) { | 
| + tracker_.Shutdown(); | 
| + EXPECT_DEBUG_DEATH( | 
| + tracker_.RunTask(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN).get()), | 
| + ""); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, | 
| + PostAndRunDuringShutdown_ContinueOnShutdown) { | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + EXPECT_EQ(1U, posted_tasks_.size()); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to post a CONTINUE_ON_SHUTDOWN task via |tracker_|. This should fail. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 
| + EXPECT_EQ(1U, posted_tasks_.size()); | 
| + | 
| + // Don't try to run the task, because it hasn't been posted successfully. | 
| + | 
| + // Unblock shutdown by running the BLOCK_SHUTDOWN task. | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, PostAndRunDuringShutdown_SkipOnShutdown) { | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + EXPECT_EQ(1U, posted_tasks_.size()); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to post a SKIP_ON_SHUTDOWN task via |tracker_|. This should fail. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 
| + EXPECT_EQ(1U, posted_tasks_.size()); | 
| + | 
| + // Don't try to run the task, because it hasn't been posted successfully. | 
| + | 
| + // Unblock shutdown by running the BLOCK_SHUTDOWN task. | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +TEST_F(TaskSchedulerTaskTrackerTest, PostAndRunDuringShutdown_BlockShutdown) { | 
| + // Post a BLOCK_SHUTDOWN task just to block shutdown. Then, call Shutdown() | 
| + // asynchronously. | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + scoped_ptr<Task> block_shutdown_task = std::move(posted_tasks_.front()); | 
| + posted_tasks_.pop(); | 
| + CallShutdownAsync(); | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + | 
| + // Try to post a BLOCK_SHUTDOWN task via |tracker_|. This should succeed. | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| + EXPECT_EQ(1U, posted_tasks_.size()); | 
| + | 
| + // Try to run the task that was just posted. This should succeed. | 
| + EXPECT_EQ(0U, num_tasks_executed_); | 
| + RunNextPostedTaskViaTracker(); | 
| + EXPECT_EQ(1U, num_tasks_executed_); | 
| + | 
| + // Unblock shutdown by running the BLOCK_SHUTDOWN task posted at the beginning | 
| + // of the test. | 
| + ExpectShutdownAsyncHasNotReturned(); | 
| + tracker_.RunTask(block_shutdown_task.get()); | 
| + EXPECT_EQ(2U, num_tasks_executed_); | 
| + JoinAndExpectShutdownAsyncHasReturned(); | 
| +} | 
| + | 
| +// This test is repeated for each TaskShutownBehavior. | 
| +TEST_P(TaskSchedulerTaskTrackerTest, PostAfterShutdown) { | 
| + // It is not possible to post a task after shutdown. | 
| + tracker_.Shutdown(); | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| + PostTaskViaTracker(CreateTask(GetParam())); | 
| + EXPECT_TRUE(posted_tasks_.empty()); | 
| +} | 
| + | 
| +INSTANTIATE_TEST_CASE_P( | 
| + ContinueOnShutdown, | 
| + TaskSchedulerTaskTrackerTest, | 
| + ::testing::Values(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 
| +INSTANTIATE_TEST_CASE_P( | 
| + SkipOnShutdown, | 
| + TaskSchedulerTaskTrackerTest, | 
| + ::testing::Values(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 
| +INSTANTIATE_TEST_CASE_P( | 
| + BlockShutdown, | 
| + TaskSchedulerTaskTrackerTest, | 
| + ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 
 
gab
2016/03/09 21:53:26
Oh nice, first time I see someone do it this way (
 
fdoray
2016/03/15 17:28:09
Acknowledged.
 
 | 
| + | 
| +} // namespace internal | 
| +} // namespace base |