Chromium Code Reviews| Index: third_party/WebKit/Source/platform/TimerTest.cpp |
| diff --git a/third_party/WebKit/Source/platform/TimerTest.cpp b/third_party/WebKit/Source/platform/TimerTest.cpp |
| index 1deae7a96cf86f43e958ae0c6cab83e86c219da5..c5e5968389516339c411a1e35c98d8fa2b090ddc 100644 |
| --- a/third_party/WebKit/Source/platform/TimerTest.cpp |
| +++ b/third_party/WebKit/Source/platform/TimerTest.cpp |
| @@ -41,10 +41,10 @@ private: |
| class DelayedTask { |
| public: |
| - DelayedTask(WebTaskRunner::Task* task, long long delayMs) |
| + DelayedTask(WebTaskRunner::Task* task, double delaySecs) |
|
esprehn
2015/09/28 23:34:43
delaySeconds
alex clarke (OOO till 29th)
2015/09/29 10:58:36
Done.
|
| : m_task(adoptRef(new RefCountedTaskContainer(task))) |
| - , m_runTimeSecs(monotonicallyIncreasingTime() + 0.001 * static_cast<double>(delayMs)) |
| - , m_delayMs(delayMs) { } |
| + , m_runTimeSecs(monotonicallyIncreasingTime() + delaySecs) |
| + , m_delaySecs(delaySecs) { } |
|
esprehn
2015/09/28 23:34:43
m_delaySeconds
alex clarke (OOO till 29th)
2015/09/29 10:58:36
Done.
|
| bool operator<(const DelayedTask& other) const |
| { |
| @@ -61,15 +61,15 @@ public: |
| return m_runTimeSecs; |
| } |
| - long long delayMs() const |
| + double delaySecs() const |
|
esprehn
2015/09/28 23:34:43
ditto, don't abbreviate
alex clarke (OOO till 29th)
2015/09/29 10:58:36
Done.
|
| { |
| - return m_delayMs; |
| + return m_delaySecs; |
| } |
| private: |
| RefPtr<RefCountedTaskContainer> m_task; |
| double m_runTimeSecs; |
|
esprehn
2015/09/28 23:34:43
This one should be fixed too
alex clarke (OOO till 29th)
2015/09/29 10:58:36
Done.
|
| - long long m_delayMs; |
| + double m_delaySecs; |
| }; |
| class MockWebTaskRunner : public WebTaskRunner { |
| @@ -82,9 +82,9 @@ public: |
| m_timerTasks->push(DelayedTask(task, 0)); |
| } |
| - void postDelayedTask(const WebTraceLocation&, Task* task, long long delayMs) override |
| + void postDelayedTask(const WebTraceLocation&, Task* task, double delayMs) override |
| { |
| - m_timerTasks->push(DelayedTask(task, delayMs)); |
| + m_timerTasks->push(DelayedTask(task, delayMs * 0.001)); |
| } |
| std::priority_queue<DelayedTask>* m_timerTasks; // NOT OWNED |
| @@ -155,15 +155,23 @@ public: |
| } |
| } |
| + void runPendingTasks() |
| + { |
| + while (!m_timerTasks.empty() && m_timerTasks.top().runTimeSecs() <= gCurrentTimeSecs) { |
| + m_timerTasks.top().run(); |
| + m_timerTasks.pop(); |
| + } |
| + } |
| + |
| bool hasOneTimerTask() const |
| { |
| return m_timerTasks.size() == 1; |
| } |
| - long nextTimerTaskDelayMillis() const |
| + double nextTimerTaskDelaySecs() const |
| { |
| ASSERT(hasOneTimerTask()); |
| - return m_timerTasks.top().delayMs(); |
| + return m_timerTasks.top().delaySecs(); |
| } |
| private: |
| @@ -240,6 +248,11 @@ public: |
| mockScheduler()->runUntilIdle(); |
| } |
| + void runPendingTasks() |
| + { |
| + mockScheduler()->runPendingTasks(); |
| + } |
| + |
| void runUntilIdleOrDeadlinePassed(double deadline) |
| { |
| mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); |
| @@ -250,9 +263,9 @@ public: |
| return mockScheduler()->hasOneTimerTask(); |
| } |
| - long nextTimerTaskDelayMillis() const |
| + double nextTimerTaskDelaySecs() const |
| { |
| - return mockScheduler()->nextTimerTaskDelayMillis(); |
| + return mockScheduler()->nextTimerTaskDelaySecs(); |
| } |
| private: |
| @@ -288,6 +301,11 @@ public: |
| m_runTimes.push_back(monotonicallyIncreasingTime()); |
| } |
| + void recordNextFireTimeTask(Timer<TimerTest>* timer) |
| + { |
| + m_nextFireTimes.push_back(monotonicallyIncreasingTime() + timer->nextFireInterval()); |
| + } |
| + |
| void advanceTimeBy(double timeSecs) |
| { |
| gCurrentTimeSecs += timeSecs; |
| @@ -298,6 +316,11 @@ public: |
| m_platform->runUntilIdle(); |
| } |
| + void runPendingTasks() |
| + { |
| + m_platform->runPendingTasks(); |
| + } |
| + |
| void runUntilIdleOrDeadlinePassed(double deadline) |
| { |
| m_platform->runUntilIdleOrDeadlinePassed(deadline); |
| @@ -308,14 +331,15 @@ public: |
| return m_platform->hasOneTimerTask(); |
| } |
| - long nextTimerTaskDelayMillis() const |
| + double nextTimerTaskDelaySecs() const |
| { |
| - return m_platform->nextTimerTaskDelayMillis(); |
| + return m_platform->nextTimerTaskDelaySecs(); |
| } |
| protected: |
| double m_startTime; |
| std::vector<double> m_runTimes; |
| + std::vector<double> m_nextFireTimes; |
|
esprehn
2015/09/28 23:34:43
These should be WTF::Vector, we don't use std::vec
alex clarke (OOO till 29th)
2015/09/29 10:58:36
I've added a todo.
|
| private: |
| OwnPtr<TimerTestPlatform> m_platform; |
| @@ -328,7 +352,7 @@ TEST_F(TimerTest, StartOneShot_Zero) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
| @@ -340,7 +364,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancel) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| timer.stop(); |
| @@ -354,7 +378,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| timer.stop(); |
| @@ -364,7 +388,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
| @@ -376,7 +400,7 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
| @@ -384,7 +408,7 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) |
| timer.startOneShot(0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime, m_startTime)); |
| @@ -396,7 +420,7 @@ TEST_F(TimerTest, StartOneShot_NonZero) |
| timer.startOneShot(10.0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
| @@ -408,7 +432,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) |
| timer.startOneShot(10, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| timer.stop(); |
| @@ -422,7 +446,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) |
| timer.startOneShot(10, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| timer.stop(); |
| @@ -433,7 +457,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) |
| timer.startOneShot(10, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(secondPostTime + 10.0)); |
| @@ -445,7 +469,7 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) |
| timer.startOneShot(10, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
| @@ -453,7 +477,7 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) |
| timer.startOneShot(20, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(20000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(20.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0, m_startTime + 30.0)); |
| @@ -466,7 +490,7 @@ TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) |
| timer.startOneShot(10, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
| runUntilIdle(); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
| @@ -498,7 +522,7 @@ TEST_F(TimerTest, StartRepeatingTask) |
| timer.startRepeating(1.0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
| runUntilIdleOrDeadlinePassed(m_startTime + 5.5); |
| EXPECT_THAT(m_runTimes, ElementsAre( |
| @@ -511,7 +535,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenCancel) |
| timer.startRepeating(1.0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
| runUntilIdleOrDeadlinePassed(m_startTime + 2.5); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); |
| @@ -528,7 +552,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) |
| timer.startRepeating(1.0, FROM_HERE); |
| ASSERT(hasOneTimerTask()); |
| - EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); |
| + EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
| runUntilIdleOrDeadlinePassed(m_startTime + 2.5); |
| EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); |
| @@ -752,6 +776,47 @@ TEST_F(TimerTest, DidChangeAlignmentInterval) |
| EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); |
| } |
| +TEST_F(TimerTest, RepeatingTimerDoesNotDrift) |
| +{ |
| + Timer<TimerTest> timer(this, &TimerTest::recordNextFireTimeTask); |
| + timer.startRepeating(2.0, FROM_HERE); |
| + |
| + ASSERT(hasOneTimerTask()); |
| + recordNextFireTimeTask(&timer); // Next scheduled task to run at m_startTime + 2.0 |
| + |
| + // Simulate timer firing early. Next scheduled task to run at m_startTime + 4.0 |
| + advanceTimeBy(1.9); |
| + runUntilIdleOrDeadlinePassed(gCurrentTimeSecs + 0.2); |
| + |
| + advanceTimeBy(2.0); |
| + runPendingTasks(); // Next scheduled task to run at m_startTime + 6.0 |
| + |
| + advanceTimeBy(2.1); |
| + runPendingTasks(); // Next scheduled task to run at m_startTime + 8.0 |
| + |
| + advanceTimeBy(2.9); |
| + runPendingTasks(); // Next scheduled task to run at m_startTime + 10.0 |
| + |
| + advanceTimeBy(3.1); |
| + runPendingTasks(); // Next scheduled task to run at m_startTime + 14.0 (skips a beat) |
| + |
| + advanceTimeBy(4.0); |
| + runPendingTasks(); // Next scheduled task to run at m_startTime + 18.0 (skips a beat) |
| + |
| + advanceTimeBy(10.0); // Next scheduled task to run at m_startTime + 28.0 (skips 5 beats) |
| + runPendingTasks(); |
| + |
| + runUntilIdleOrDeadlinePassed(m_startTime + 5.5); |
| + EXPECT_THAT(m_nextFireTimes, ElementsAre( |
| + m_startTime + 2.0, |
| + m_startTime + 4.0, |
| + m_startTime + 6.0, |
| + m_startTime + 8.0, |
| + m_startTime + 10.0, |
| + m_startTime + 14.0, |
| + m_startTime + 18.0, |
| + m_startTime + 28.0)); |
| +} |
| } // namespace |
| } // namespace blink |