Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/callback.h" | |
| 5 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/synchronization/waitable_event.h" | |
| 9 #include "base/test/sequenced_worker_pool_owner.h" | |
| 7 #include "base/test/test_simple_task_runner.h" | 10 #include "base/test/test_simple_task_runner.h" |
| 8 #include "base/timer/timer.h" | 11 #include "base/timer/timer.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 13 |
| 14 using base::SequencedTaskRunner; | |
| 11 using base::TimeDelta; | 15 using base::TimeDelta; |
| 12 using base::SingleThreadTaskRunner; | |
| 13 | 16 |
| 14 namespace { | 17 namespace { |
| 15 | 18 |
| 16 // The message loops on which each timer should be tested. | 19 // The message loops on which each timer should be tested. |
| 17 const base::MessageLoop::Type testing_message_loops[] = { | 20 const base::MessageLoop::Type testing_message_loops[] = { |
| 18 base::MessageLoop::TYPE_DEFAULT, | 21 base::MessageLoop::TYPE_DEFAULT, |
| 19 base::MessageLoop::TYPE_IO, | 22 base::MessageLoop::TYPE_IO, |
| 20 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. | 23 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. |
| 21 base::MessageLoop::TYPE_UI, | 24 base::MessageLoop::TYPE_UI, |
| 22 #endif | 25 #endif |
| 23 }; | 26 }; |
| 24 | 27 |
| 25 const int kNumTestingMessageLoops = arraysize(testing_message_loops); | 28 const int kNumTestingMessageLoops = arraysize(testing_message_loops); |
| 26 | 29 |
| 27 class OneShotTimerTester { | 30 class OneShotTimerTester { |
| 28 public: | 31 public: |
| 29 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) | 32 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) |
| 30 : did_run_(did_run), | 33 : did_run_(did_run), |
| 31 delay_ms_(milliseconds), | 34 delay_ms_(milliseconds), |
| 32 quit_message_loop_(true) { | 35 quit_message_loop_(true) { |
| 33 } | 36 } |
| 34 | 37 |
| 35 void Start() { | 38 void Start() { |
| 36 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, | 39 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, |
| 37 &OneShotTimerTester::Run); | 40 &OneShotTimerTester::Run); |
| 38 } | 41 } |
| 39 | 42 |
| 40 void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) { | 43 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) { |
| 41 quit_message_loop_ = false; | 44 quit_message_loop_ = false; |
| 42 timer_.SetTaskRunner(task_runner); | 45 timer_.SetTaskRunner(task_runner); |
| 43 } | 46 } |
| 44 | 47 |
| 45 private: | 48 private: |
| 46 void Run() { | 49 void Run() { |
| 47 *did_run_ = true; | 50 *did_run_ = true; |
| 48 if (quit_message_loop_) { | 51 if (quit_message_loop_) { |
| 49 base::MessageLoop::current()->QuitWhenIdle(); | 52 base::MessageLoop::current()->QuitWhenIdle(); |
| 50 } | 53 } |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10), | 524 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10), |
| 522 base::Bind(&SetCallbackHappened1)); | 525 base::Bind(&SetCallbackHappened1)); |
| 523 timer.Reset(); | 526 timer.Reset(); |
| 524 // Since Reset happened before task ran, the user_task must not be cleared: | 527 // Since Reset happened before task ran, the user_task must not be cleared: |
| 525 ASSERT_FALSE(timer.user_task().is_null()); | 528 ASSERT_FALSE(timer.user_task().is_null()); |
| 526 base::MessageLoop::current()->Run(); | 529 base::MessageLoop::current()->Run(); |
| 527 EXPECT_TRUE(g_callback_happened1); | 530 EXPECT_TRUE(g_callback_happened1); |
| 528 } | 531 } |
| 529 } | 532 } |
| 530 | 533 |
| 534 const size_t kNumWorkerThreads = 3; | |
| 535 | |
| 536 // Fixture for tests requiring a worker pool. Includes a WaitableEvent so | |
| 537 // that cases may Wait() on one thread and Signal() (explicitly, or implicitly | |
| 538 // via helper methods) on another. | |
| 539 class TimerSequenceTest : public testing::Test { | |
| 540 public: | |
| 541 TimerSequenceTest() | |
| 542 : 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.
| |
| 543 | |
| 544 void SetUp() override { ResetPool(); } | |
| 545 | |
| 546 void TearDown() override { pool()->Shutdown(); } | |
| 547 | |
| 548 // Block until Signal() is called on another thread. | |
| 549 void Wait() { event_.Wait(); } | |
| 550 | |
| 551 void Signal() { event_.Signal(); } | |
| 552 | |
| 553 // Explicitly create the timer. Not done in the constructor so that test | |
| 554 // cases demonstrate creation on a specific thread. | |
| 555 void CreateTimer() { timer_.reset(new base::OneShotTimer); } | |
| 556 | |
| 557 // Start the timer; when the timer fires it will Signal(), so Wait() can | |
| 558 // be called on another thread to await this. | |
| 559 void StartTimerWillSignal() { | |
| 560 timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(1), this, | |
| 561 &TimerSequenceTest::Signal); | |
| 562 } | |
| 563 | |
| 564 // Delete the timer then Signal() so that this can be posted as a task | |
| 565 // to another thread and the poster can Wait(). | |
| 566 void DeleteTimerAndSignal() { | |
| 567 timer_.reset(); | |
| 568 Signal(); | |
| 569 } | |
| 570 | |
| 571 protected: | |
| 572 const scoped_refptr<base::SequencedWorkerPool>& pool() { | |
| 573 return pool_owner_->pool(); | |
| 574 } | |
| 575 | |
| 576 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut | |
| 577 // down, and creates a new instance. | |
| 578 void ResetPool() { | |
| 579 pool_owner_.reset( | |
| 580 new base::SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); | |
| 581 } | |
| 582 | |
| 583 scoped_ptr<base::OneShotTimer> timer_; | |
| 584 | |
| 585 private: | |
| 586 base::WaitableEvent event_; | |
| 587 | |
| 588 base::MessageLoop message_loop_; | |
| 589 scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_; | |
| 590 }; | |
|
gab
2015/12/03 22:26:08
DISALLOW_COPY_AND_ASSIGN
jsbell
2015/12/05 01:15:39
Done.
| |
| 591 | |
| 592 TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolThread) { | |
| 593 scoped_refptr<base::SequencedTaskRunner> task_runner = | |
| 594 pool()->GetSequencedTaskRunner(pool()->GetSequenceToken()); | |
| 595 | |
| 596 // Timer is created on this thread. | |
| 597 CreateTimer(); | |
| 598 | |
| 599 // Task will execute on a pool thread. | |
| 600 timer_->SetTaskRunner(task_runner.get()); | |
| 601 StartTimerWillSignal(); | |
| 602 Wait(); | |
| 603 | |
| 604 // Timer will be destroyed on this thread. | |
| 605 timer_.reset(); | |
| 606 } | |
| 607 | |
| 608 TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolThread) { | |
| 609 scoped_refptr<base::SequencedTaskRunner> task_runner = | |
| 610 pool()->GetSequencedTaskRunner(pool()->GetSequenceToken()); | |
| 611 | |
| 612 // Timer is created on this thread. | |
| 613 CreateTimer(); | |
| 614 | |
| 615 // Task will execute on a pool thread. | |
| 616 task_runner->PostTask(FROM_HERE, | |
| 617 base::Bind(&TimerSequenceTest::StartTimerWillSignal, | |
| 618 base::Unretained(this))); | |
| 619 Wait(); | |
| 620 | |
| 621 // Timer must be destroyed on pool thread, too. | |
| 622 task_runner->PostTask(FROM_HERE, | |
| 623 base::Bind(&TimerSequenceTest::DeleteTimerAndSignal, | |
| 624 base::Unretained(this))); | |
| 625 Wait(); | |
| 626 } | |
| 627 | |
|
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?
| |
| 531 } // namespace | 628 } // namespace |
| OLD | NEW |