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); |