Chromium Code Reviews| Index: base/timer/timer_unittest.cc |
| diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc |
| index 35e4315ea46368b392fd7e861398ba0440eb8a79..1a39821b76280b7442f6436d2a5a8c7fc563e28e 100644 |
| --- a/base/timer/timer_unittest.cc |
| +++ b/base/timer/timer_unittest.cc |
| @@ -2,14 +2,17 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "base/callback.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "base/test/sequenced_worker_pool_owner.h" |
| #include "base/test/test_simple_task_runner.h" |
| #include "base/timer/timer.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +using base::SequencedTaskRunner; |
| using base::TimeDelta; |
| -using base::SingleThreadTaskRunner; |
| namespace { |
| @@ -37,7 +40,7 @@ class OneShotTimerTester { |
| &OneShotTimerTester::Run); |
| } |
| - void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) { |
| + void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) { |
| quit_message_loop_ = false; |
| timer_.SetTaskRunner(task_runner); |
| } |
| @@ -528,4 +531,98 @@ TEST(TimerTest, ContinuationReset) { |
| } |
| } |
| +const size_t kNumWorkerThreads = 3; |
| + |
| +// Fixture for tests requiring a worker pool. Includes a WaitableEvent so |
| +// that cases may Wait() on one thread and Signal() (explicitly, or implicitly |
| +// via helper methods) on another. |
| +class TimerSequenceTest : public testing::Test { |
| + public: |
| + TimerSequenceTest() |
| + : event_(false /*manual_reset*/, true /*initially_signaled*/) {} |
|
gab
2015/12/03 22:26:08
Add space padding in /* comment */
jsbell
2015/12/05 01:15:39
Done.
|
| + |
| + void SetUp() override { ResetPool(); } |
| + |
| + void TearDown() override { pool()->Shutdown(); } |
| + |
| + // Block until Signal() is called on another thread. |
| + void Wait() { event_.Wait(); } |
| + |
| + void Signal() { event_.Signal(); } |
| + |
| + // Explicitly create the timer. Not done in the constructor so that test |
| + // cases demonstrate creation on a specific thread. |
| + void CreateTimer() { timer_.reset(new base::OneShotTimer); } |
| + |
| + // Start the timer; when the timer fires it will Signal(), so Wait() can |
| + // be called on another thread to await this. |
| + void StartTimerWillSignal() { |
| + timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(1), this, |
| + &TimerSequenceTest::Signal); |
| + } |
| + |
| + // Delete the timer then Signal() so that this can be posted as a task |
| + // to another thread and the poster can Wait(). |
| + void DeleteTimerAndSignal() { |
| + timer_.reset(); |
| + Signal(); |
| + } |
| + |
| + protected: |
| + const scoped_refptr<base::SequencedWorkerPool>& pool() { |
| + return pool_owner_->pool(); |
| + } |
| + |
| + // Destroys the SequencedWorkerPool instance, blocking until it is fully shut |
| + // down, and creates a new instance. |
| + void ResetPool() { |
| + pool_owner_.reset( |
| + new base::SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); |
| + } |
| + |
| + scoped_ptr<base::OneShotTimer> timer_; |
| + |
| + private: |
| + base::WaitableEvent event_; |
| + |
| + base::MessageLoop message_loop_; |
| + scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_; |
| +}; |
|
gab
2015/12/03 22:26:08
DISALLOW_COPY_AND_ASSIGN
jsbell
2015/12/05 01:15:39
Done.
|
| + |
| +TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolThread) { |
| + scoped_refptr<base::SequencedTaskRunner> task_runner = |
| + pool()->GetSequencedTaskRunner(pool()->GetSequenceToken()); |
| + |
| + // Timer is created on this thread. |
| + CreateTimer(); |
| + |
| + // Task will execute on a pool thread. |
| + timer_->SetTaskRunner(task_runner.get()); |
| + StartTimerWillSignal(); |
| + Wait(); |
| + |
| + // Timer will be destroyed on this thread. |
| + timer_.reset(); |
| +} |
| + |
| +TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolThread) { |
| + scoped_refptr<base::SequencedTaskRunner> task_runner = |
| + pool()->GetSequencedTaskRunner(pool()->GetSequenceToken()); |
| + |
| + // Timer is created on this thread. |
| + CreateTimer(); |
| + |
| + // Task will execute on a pool thread. |
| + task_runner->PostTask(FROM_HERE, |
| + base::Bind(&TimerSequenceTest::StartTimerWillSignal, |
| + base::Unretained(this))); |
| + Wait(); |
| + |
| + // Timer must be destroyed on pool thread, too. |
| + task_runner->PostTask(FROM_HERE, |
| + base::Bind(&TimerSequenceTest::DeleteTimerAndSignal, |
| + base::Unretained(this))); |
| + Wait(); |
| +} |
| + |
|
gab
2015/12/03 22:26:09
Feels a test that would:
1) Create a |timer| from
jsbell
2015/12/05 01:15:39
Those sound great - done and done. Any others?
|
| } // namespace |