| Index: base/timer_unittest.cc
|
| ===================================================================
|
| --- base/timer_unittest.cc (revision 1824)
|
| +++ base/timer_unittest.cc (working copy)
|
| @@ -7,326 +7,8 @@
|
| #include "base/timer.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| -using base::TimerComparison;
|
| -
|
| namespace {
|
|
|
| -class TimerTest : public testing::Test {};
|
| -
|
| -// A base class timer task that sanity-checks timer functionality and counts
|
| -// the number of times it has run. Handles all message loop and memory
|
| -// management issues.
|
| -class TimerTask : public Task {
|
| - public:
|
| - // Runs all timers to completion. This returns only after all timers have
|
| - // finished firing.
|
| - static void RunTimers();
|
| -
|
| - // Creates a new timer. If |repeating| is true, the timer will repeat 10
|
| - // times before terminating.
|
| - //
|
| - // All timers are managed on the message loop of the thread that calls this
|
| - // function the first time.
|
| - TimerTask(int delay, bool repeating);
|
| -
|
| - virtual ~TimerTask();
|
| -
|
| - int iterations() const { return iterations_; }
|
| - const Timer* timer() const { return timer_; }
|
| -
|
| - // Resets the timer, if it exists.
|
| - void Reset();
|
| -
|
| - // Task
|
| - virtual void Run();
|
| -
|
| - protected:
|
| - // Shuts down the message loop if necessary.
|
| - static void QuitMessageLoop();
|
| -
|
| - private:
|
| - static MessageLoop* message_loop() {
|
| - return MessageLoop::current();
|
| - }
|
| -
|
| - static int timer_count_;
|
| - static bool loop_running_;
|
| -
|
| - bool timer_running_;
|
| - int delay_;
|
| - TimeTicks start_ticks_;
|
| - int iterations_;
|
| - Timer* timer_;
|
| -};
|
| -
|
| -// static
|
| -void TimerTask::RunTimers() {
|
| - if (timer_count_ && !loop_running_) {
|
| - loop_running_ = true;
|
| - message_loop()->Run();
|
| - }
|
| -}
|
| -
|
| -TimerTask::TimerTask(int delay, bool repeating)
|
| - : timer_running_(false),
|
| - delay_(delay),
|
| - start_ticks_(TimeTicks::Now()),
|
| - iterations_(0),
|
| - timer_(NULL) {
|
| - Reset(); // This will just set up the variables to indicate we have a
|
| - // running timer.
|
| - timer_ = message_loop()->timer_manager_deprecated()->StartTimer(
|
| - delay, this, repeating);
|
| -}
|
| -
|
| -TimerTask::~TimerTask() {
|
| - if (timer_) {
|
| - message_loop()->timer_manager_deprecated()->StopTimer(timer_);
|
| - delete timer_;
|
| - }
|
| - if (timer_running_) {
|
| - timer_running_ = false;
|
| - if (--timer_count_ <= 0)
|
| - QuitMessageLoop();
|
| - }
|
| -}
|
| -
|
| -void TimerTask::Reset() {
|
| - if (!timer_running_) {
|
| - timer_running_ = true;
|
| - ++timer_count_;
|
| - }
|
| - if (timer_) {
|
| - start_ticks_ = TimeTicks::Now();
|
| - message_loop()->timer_manager_deprecated()->ResetTimer(timer_);
|
| - }
|
| -}
|
| -
|
| -void TimerTask::Run() {
|
| - ++iterations_;
|
| -
|
| - // Test that we fired on or after the delay, not before.
|
| - const TimeTicks ticks = TimeTicks::Now();
|
| - EXPECT_LE(delay_, (ticks - start_ticks_).InMilliseconds());
|
| - // Note: Add the delay rather than using the ticks recorded.
|
| - // Repeating timers have already started ticking before
|
| - // this callback; we pretend they started *now*, then
|
| - // it might seem like they fire early, when they do not.
|
| - start_ticks_ += TimeDelta::FromMilliseconds(delay_);
|
| -
|
| - // If we're done running, shut down the message loop.
|
| - if (timer_->repeating() && (iterations_ < 10))
|
| - return; // Iterate 10 times before terminating.
|
| - message_loop()->timer_manager_deprecated()->StopTimer(timer_);
|
| - timer_running_ = false;
|
| - if (--timer_count_ <= 0)
|
| - QuitMessageLoop();
|
| -}
|
| -
|
| -// static
|
| -void TimerTask::QuitMessageLoop() {
|
| - if (loop_running_) {
|
| - message_loop()->Quit();
|
| - loop_running_ = false;
|
| - }
|
| -}
|
| -
|
| -int TimerTask::timer_count_ = 0;
|
| -bool TimerTask::loop_running_ = false;
|
| -
|
| -// A task that deletes itself when run.
|
| -class DeletingTask : public TimerTask {
|
| - public:
|
| - DeletingTask(int delay, bool repeating) : TimerTask(delay, repeating) { }
|
| -
|
| - // Task
|
| - virtual void Run();
|
| -};
|
| -
|
| -void DeletingTask::Run() {
|
| - delete this;
|
| -
|
| - // Can't call TimerTask::Run() here, we've destroyed ourselves.
|
| -}
|
| -
|
| -// A class that resets another TimerTask when run.
|
| -class ResettingTask : public TimerTask {
|
| - public:
|
| - ResettingTask(int delay, bool repeating, TimerTask* task)
|
| - : TimerTask(delay, repeating),
|
| - task_(task) {
|
| - }
|
| -
|
| - virtual void Run();
|
| -
|
| - private:
|
| - TimerTask* task_;
|
| -};
|
| -
|
| -void ResettingTask::Run() {
|
| - task_->Reset();
|
| -
|
| - TimerTask::Run();
|
| -}
|
| -
|
| -// A class that quits the message loop when run.
|
| -class QuittingTask : public TimerTask {
|
| - public:
|
| - QuittingTask(int delay, bool repeating) : TimerTask(delay, repeating) { }
|
| -
|
| - virtual void Run();
|
| -};
|
| -
|
| -void QuittingTask::Run() {
|
| - QuitMessageLoop();
|
| -
|
| - TimerTask::Run();
|
| -}
|
| -
|
| -void RunTimerTest() {
|
| - // Make sure oneshot timers work correctly.
|
| - TimerTask task1(100, false);
|
| - TimerTask::RunTimers();
|
| - EXPECT_EQ(1, task1.iterations());
|
| -
|
| - // Make sure repeating timers work correctly.
|
| - TimerTask task2(10, true);
|
| - TimerTask task3(100, true);
|
| - TimerTask::RunTimers();
|
| - EXPECT_EQ(10, task2.iterations());
|
| - EXPECT_EQ(10, task3.iterations());
|
| -}
|
| -
|
| -//-----------------------------------------------------------------------------
|
| -// The timer test cases:
|
| -
|
| -void RunTest_TimerComparison(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - // Make sure TimerComparison sorts correctly.
|
| - const TimerTask task1(10, false);
|
| - const Timer* timer1 = task1.timer();
|
| - const TimerTask task2(200, false);
|
| - const Timer* timer2 = task2.timer();
|
| - TimerComparison comparison;
|
| - EXPECT_FALSE(comparison(timer1, timer2));
|
| - EXPECT_TRUE(comparison(timer2, timer1));
|
| -}
|
| -
|
| -void RunTest_BasicTimer(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - RunTimerTest();
|
| -}
|
| -
|
| -void RunTest_BrokenTimer(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - // Simulate faulty early-firing timers. The tasks in RunTimerTest should
|
| - // nevertheless be invoked after their specified delays, regardless of when
|
| - // WM_TIMER fires.
|
| - TimerManager* manager = MessageLoop::current()->timer_manager_deprecated();
|
| - manager->set_use_broken_delay(true);
|
| - RunTimerTest();
|
| - manager->set_use_broken_delay(false);
|
| -}
|
| -
|
| -void RunTest_DeleteFromRun(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - // Make sure TimerManager correctly handles a Task that deletes itself when
|
| - // run.
|
| - new DeletingTask(50, true);
|
| - TimerTask timer_task(150, false);
|
| - new DeletingTask(250, true);
|
| - TimerTask::RunTimers();
|
| - EXPECT_EQ(1, timer_task.iterations());
|
| -}
|
| -
|
| -void RunTest_Reset(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - // Make sure resetting a timer after it has fired works.
|
| - TimerTask timer_task1(250, false);
|
| - TimerTask timer_task2(100, true);
|
| - ResettingTask resetting_task1(600, false, &timer_task1);
|
| - TimerTask::RunTimers();
|
| - EXPECT_EQ(2, timer_task1.iterations());
|
| - EXPECT_EQ(10, timer_task2.iterations());
|
| -
|
| - // Make sure resetting a timer before it has fired works. This will reset
|
| - // two timers, then stop the message loop between when they should have
|
| - // finally fired.
|
| - TimerTask timer_task3(100, false);
|
| - TimerTask timer_task4(600, false);
|
| - ResettingTask resetting_task3(50, false, &timer_task3);
|
| - ResettingTask resetting_task4(50, false, &timer_task4);
|
| - QuittingTask quitting_task(300, false);
|
| - TimerTask::RunTimers();
|
| - EXPECT_EQ(1, timer_task3.iterations());
|
| - EXPECT_EQ(0, timer_task4.iterations());
|
| -}
|
| -
|
| -void RunTest_FifoOrder(MessageLoop::Type message_loop_type) {
|
| - MessageLoop loop(message_loop_type);
|
| -
|
| - // Creating timers with the same timeout should
|
| - // always compare to result in FIFO ordering.
|
| -
|
| - // Derive from the timer so that we can set it's fire time.
|
| - // We have to do this, because otherwise, it's possible for
|
| - // two timers, created back to back, to have different times,
|
| - // and in that case, we aren't really testing what we want
|
| - // to test!
|
| - class MockTimer : public Timer {
|
| - public:
|
| - MockTimer(int delay) : Timer(delay, NULL, false) {}
|
| - void set_fire_time(const Time& t) { fire_time_ = t; }
|
| - };
|
| -
|
| - class MockTimerManager : public TimerManager {
|
| - public:
|
| - MockTimerManager() : TimerManager(MessageLoop::current()) {
|
| - }
|
| -
|
| - // Pops the most-recent to fire timer and returns its timer id.
|
| - // Returns -1 if there are no timers in the list.
|
| - int pop() {
|
| - int rv = -1;
|
| - Timer* top = PeekTopTimer();
|
| - if (top) {
|
| - rv = top->id();
|
| - StopTimer(top);
|
| - delete top;
|
| - }
|
| - return rv;
|
| - }
|
| - };
|
| -
|
| - MockTimer t1(0);
|
| - MockTimer t2(0);
|
| - t2.set_fire_time(t1.fire_time());
|
| - TimerComparison comparison;
|
| - EXPECT_TRUE(comparison(&t2, &t1));
|
| -
|
| - // Issue a tight loop of timers; most will have the
|
| - // same timestamp; some will not. Either way, since
|
| - // all are created with delay(0), the second timer
|
| - // must always be greater than the first. Then, pop
|
| - // all the timers and verify that it's a FIFO list.
|
| - MockTimerManager manager;
|
| - const int kNumTimers = 1024;
|
| - for (int i=0; i < kNumTimers; i++)
|
| - manager.StartTimer(0, NULL, false);
|
| -
|
| - int last_id = -1;
|
| - int new_id = 0;
|
| - while((new_id = manager.pop()) > 0)
|
| - EXPECT_GT(new_id, last_id);
|
| -}
|
| -
|
| -namespace {
|
| -
|
| class OneShotTimerTester {
|
| public:
|
| OneShotTimerTester(bool* did_run) : did_run_(did_run) {
|
| @@ -364,8 +46,6 @@
|
| base::RepeatingTimer<RepeatingTimerTester> timer_;
|
| };
|
|
|
| -} // namespace
|
| -
|
| void RunTest_OneShotTimer(MessageLoop::Type message_loop_type) {
|
| MessageLoop loop(message_loop_type);
|
|
|
| @@ -440,42 +120,6 @@
|
| // Each test is run against each type of MessageLoop. That way we are sure
|
| // that timers work properly in all configurations.
|
|
|
| -TEST(TimerTest, TimerComparison) {
|
| - RunTest_TimerComparison(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_TimerComparison(MessageLoop::TYPE_UI);
|
| - RunTest_TimerComparison(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| -TEST(TimerTest, BasicTimer) {
|
| - RunTest_BasicTimer(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_BasicTimer(MessageLoop::TYPE_UI);
|
| - RunTest_BasicTimer(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| -TEST(TimerTest, BrokenTimer) {
|
| - RunTest_BrokenTimer(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_BrokenTimer(MessageLoop::TYPE_UI);
|
| - RunTest_BrokenTimer(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| -TEST(TimerTest, DeleteFromRun) {
|
| - RunTest_DeleteFromRun(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_DeleteFromRun(MessageLoop::TYPE_UI);
|
| - RunTest_DeleteFromRun(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| -TEST(TimerTest, Reset) {
|
| - RunTest_Reset(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_Reset(MessageLoop::TYPE_UI);
|
| - RunTest_Reset(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| -TEST(TimerTest, FifoOrder) {
|
| - RunTest_FifoOrder(MessageLoop::TYPE_DEFAULT);
|
| - RunTest_FifoOrder(MessageLoop::TYPE_UI);
|
| - RunTest_FifoOrder(MessageLoop::TYPE_IO);
|
| -}
|
| -
|
| TEST(TimerTest, OneShotTimer) {
|
| RunTest_OneShotTimer(MessageLoop::TYPE_DEFAULT);
|
| RunTest_OneShotTimer(MessageLoop::TYPE_UI);
|
|
|