OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "config.h" | 5 #include "config.h" |
6 #include "platform/Timer.h" | 6 #include "platform/Timer.h" |
7 | 7 |
8 #include "public/platform/Platform.h" | 8 #include "public/platform/Platform.h" |
9 #include "public/platform/WebScheduler.h" | 9 #include "public/platform/WebScheduler.h" |
10 #include "public/platform/WebThread.h" | 10 #include "public/platform/WebThread.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 { | 34 { |
35 m_task->run(); | 35 m_task->run(); |
36 } | 36 } |
37 | 37 |
38 private: | 38 private: |
39 OwnPtr<WebTaskRunner::Task> m_task; | 39 OwnPtr<WebTaskRunner::Task> m_task; |
40 }; | 40 }; |
41 | 41 |
42 class DelayedTask { | 42 class DelayedTask { |
43 public: | 43 public: |
44 DelayedTask(WebTaskRunner::Task* task, long long delayMs) | 44 DelayedTask(WebTaskRunner::Task* task, double delaySeconds) |
45 : m_task(adoptRef(new RefCountedTaskContainer(task))) | 45 : m_task(adoptRef(new RefCountedTaskContainer(task))) |
46 , m_runTimeSecs(monotonicallyIncreasingTime() + 0.001 * static_cast<doub
le>(delayMs)) | 46 , m_runTimeSeconds(monotonicallyIncreasingTime() + delaySeconds) |
47 , m_delayMs(delayMs) { } | 47 , m_delaySeconds(delaySeconds) { } |
48 | 48 |
49 bool operator<(const DelayedTask& other) const | 49 bool operator<(const DelayedTask& other) const |
50 { | 50 { |
51 return m_runTimeSecs > other.m_runTimeSecs; | 51 return m_runTimeSeconds > other.m_runTimeSeconds; |
52 } | 52 } |
53 | 53 |
54 void run() const | 54 void run() const |
55 { | 55 { |
56 m_task->run(); | 56 m_task->run(); |
57 } | 57 } |
58 | 58 |
59 double runTimeSecs() const | 59 double runTimeSeconds() const |
60 { | 60 { |
61 return m_runTimeSecs; | 61 return m_runTimeSeconds; |
62 } | 62 } |
63 | 63 |
64 long long delayMs() const | 64 double delaySeconds() const |
65 { | 65 { |
66 return m_delayMs; | 66 return m_delaySeconds; |
67 } | 67 } |
68 | 68 |
69 private: | 69 private: |
70 RefPtr<RefCountedTaskContainer> m_task; | 70 RefPtr<RefCountedTaskContainer> m_task; |
71 double m_runTimeSecs; | 71 double m_runTimeSeconds; |
72 long long m_delayMs; | 72 double m_delaySeconds; |
73 }; | 73 }; |
74 | 74 |
75 class MockWebTaskRunner : public WebTaskRunner { | 75 class MockWebTaskRunner : public WebTaskRunner { |
76 public: | 76 public: |
77 explicit MockWebTaskRunner(std::priority_queue<DelayedTask>* timerTasks) : m
_timerTasks(timerTasks) { } | 77 explicit MockWebTaskRunner(std::priority_queue<DelayedTask>* timerTasks) : m
_timerTasks(timerTasks) { } |
78 ~MockWebTaskRunner() override { } | 78 ~MockWebTaskRunner() override { } |
79 | 79 |
80 virtual void postTask(const WebTraceLocation&, Task* task) | 80 virtual void postTask(const WebTraceLocation&, Task* task) |
81 { | 81 { |
82 m_timerTasks->push(DelayedTask(task, 0)); | 82 m_timerTasks->push(DelayedTask(task, 0)); |
83 } | 83 } |
84 | 84 |
85 void postDelayedTask(const WebTraceLocation&, Task* task, long long delayMs)
override | 85 void postDelayedTask(const WebTraceLocation&, Task* task, double delayMs) ov
erride |
86 { | 86 { |
87 m_timerTasks->push(DelayedTask(task, delayMs)); | 87 m_timerTasks->push(DelayedTask(task, delayMs * 0.001)); |
88 } | 88 } |
89 | 89 |
90 std::priority_queue<DelayedTask>* m_timerTasks; // NOT OWNED | 90 std::priority_queue<DelayedTask>* m_timerTasks; // NOT OWNED |
91 }; | 91 }; |
92 | 92 |
93 class MockWebScheduler : public WebScheduler { | 93 class MockWebScheduler : public WebScheduler { |
94 public: | 94 public: |
95 MockWebScheduler() : m_timerWebTaskRunner(&m_timerTasks) { } | 95 MockWebScheduler() : m_timerWebTaskRunner(&m_timerTasks) { } |
96 ~MockWebScheduler() override { } | 96 ~MockWebScheduler() override { } |
97 | 97 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 } | 129 } |
130 | 130 |
131 void postTimerTaskAt(const WebTraceLocation&, WebTaskRunner::Task* task, dou
ble monotonicTime) override | 131 void postTimerTaskAt(const WebTraceLocation&, WebTaskRunner::Task* task, dou
ble monotonicTime) override |
132 { | 132 { |
133 m_timerTasks.push(DelayedTask(task, (monotonicTime - monotonicallyIncrea
singTime()) * 1000)); | 133 m_timerTasks.push(DelayedTask(task, (monotonicTime - monotonicallyIncrea
singTime()) * 1000)); |
134 } | 134 } |
135 | 135 |
136 void runUntilIdle() | 136 void runUntilIdle() |
137 { | 137 { |
138 while (!m_timerTasks.empty()) { | 138 while (!m_timerTasks.empty()) { |
139 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs(); | 139 gCurrentTimeSecs = m_timerTasks.top().runTimeSeconds(); |
140 m_timerTasks.top().run(); | 140 m_timerTasks.top().run(); |
141 m_timerTasks.pop(); | 141 m_timerTasks.pop(); |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 void runUntilIdleOrDeadlinePassed(double deadline) | 145 void runUntilIdleOrDeadlinePassed(double deadline) |
146 { | 146 { |
147 while (!m_timerTasks.empty()) { | 147 while (!m_timerTasks.empty()) { |
148 if (m_timerTasks.top().runTimeSecs() > deadline) { | 148 if (m_timerTasks.top().runTimeSeconds() > deadline) { |
149 gCurrentTimeSecs = deadline; | 149 gCurrentTimeSecs = deadline; |
150 break; | 150 break; |
151 } | 151 } |
152 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs(); | 152 gCurrentTimeSecs = m_timerTasks.top().runTimeSeconds(); |
153 m_timerTasks.top().run(); | 153 m_timerTasks.top().run(); |
154 m_timerTasks.pop(); | 154 m_timerTasks.pop(); |
155 } | 155 } |
| 156 } |
| 157 |
| 158 void runPendingTasks() |
| 159 { |
| 160 while (!m_timerTasks.empty() && m_timerTasks.top().runTimeSeconds() <= g
CurrentTimeSecs) { |
| 161 m_timerTasks.top().run(); |
| 162 m_timerTasks.pop(); |
| 163 } |
156 } | 164 } |
157 | 165 |
158 bool hasOneTimerTask() const | 166 bool hasOneTimerTask() const |
159 { | 167 { |
160 return m_timerTasks.size() == 1; | 168 return m_timerTasks.size() == 1; |
161 } | 169 } |
162 | 170 |
163 long nextTimerTaskDelayMillis() const | 171 double nextTimerTaskDelaySecs() const |
164 { | 172 { |
165 ASSERT(hasOneTimerTask()); | 173 ASSERT(hasOneTimerTask()); |
166 return m_timerTasks.top().delayMs(); | 174 return m_timerTasks.top().delaySeconds(); |
167 } | 175 } |
168 | 176 |
169 private: | 177 private: |
170 std::priority_queue<DelayedTask> m_timerTasks; | 178 std::priority_queue<DelayedTask> m_timerTasks; |
171 MockWebTaskRunner m_timerWebTaskRunner; | 179 MockWebTaskRunner m_timerWebTaskRunner; |
172 }; | 180 }; |
173 | 181 |
174 class FakeWebThread : public WebThread { | 182 class FakeWebThread : public WebThread { |
175 public: | 183 public: |
176 FakeWebThread() : m_webScheduler(adoptPtr(new MockWebScheduler())) { } | 184 FakeWebThread() : m_webScheduler(adoptPtr(new MockWebScheduler())) { } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 { | 241 { |
234 static const unsigned char enabled[] = {0}; | 242 static const unsigned char enabled[] = {0}; |
235 return enabled; | 243 return enabled; |
236 } | 244 } |
237 | 245 |
238 void runUntilIdle() | 246 void runUntilIdle() |
239 { | 247 { |
240 mockScheduler()->runUntilIdle(); | 248 mockScheduler()->runUntilIdle(); |
241 } | 249 } |
242 | 250 |
| 251 void runPendingTasks() |
| 252 { |
| 253 mockScheduler()->runPendingTasks(); |
| 254 } |
| 255 |
243 void runUntilIdleOrDeadlinePassed(double deadline) | 256 void runUntilIdleOrDeadlinePassed(double deadline) |
244 { | 257 { |
245 mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); | 258 mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); |
246 } | 259 } |
247 | 260 |
248 bool hasOneTimerTask() const | 261 bool hasOneTimerTask() const |
249 { | 262 { |
250 return mockScheduler()->hasOneTimerTask(); | 263 return mockScheduler()->hasOneTimerTask(); |
251 } | 264 } |
252 | 265 |
253 long nextTimerTaskDelayMillis() const | 266 double nextTimerTaskDelaySecs() const |
254 { | 267 { |
255 return mockScheduler()->nextTimerTaskDelayMillis(); | 268 return mockScheduler()->nextTimerTaskDelaySecs(); |
256 } | 269 } |
257 | 270 |
258 private: | 271 private: |
259 MockWebScheduler* mockScheduler() const | 272 MockWebScheduler* mockScheduler() const |
260 { | 273 { |
261 return static_cast<MockWebScheduler*>(m_webThread->scheduler()); | 274 return static_cast<MockWebScheduler*>(m_webThread->scheduler()); |
262 } | 275 } |
263 | 276 |
264 OwnPtr<FakeWebThread> m_webThread; | 277 OwnPtr<FakeWebThread> m_webThread; |
265 }; | 278 }; |
(...skipping 15 matching lines...) Expand all Loading... |
281 void TearDown() override | 294 void TearDown() override |
282 { | 295 { |
283 Platform::initialize(m_oldPlatform); | 296 Platform::initialize(m_oldPlatform); |
284 } | 297 } |
285 | 298 |
286 void countingTask(Timer<TimerTest>*) | 299 void countingTask(Timer<TimerTest>*) |
287 { | 300 { |
288 m_runTimes.push_back(monotonicallyIncreasingTime()); | 301 m_runTimes.push_back(monotonicallyIncreasingTime()); |
289 } | 302 } |
290 | 303 |
| 304 void recordNextFireTimeTask(Timer<TimerTest>* timer) |
| 305 { |
| 306 m_nextFireTimes.push_back(monotonicallyIncreasingTime() + timer->nextFir
eInterval()); |
| 307 } |
| 308 |
291 void advanceTimeBy(double timeSecs) | 309 void advanceTimeBy(double timeSecs) |
292 { | 310 { |
293 gCurrentTimeSecs += timeSecs; | 311 gCurrentTimeSecs += timeSecs; |
294 } | 312 } |
295 | 313 |
296 void runUntilIdle() | 314 void runUntilIdle() |
297 { | 315 { |
298 m_platform->runUntilIdle(); | 316 m_platform->runUntilIdle(); |
299 } | 317 } |
300 | 318 |
| 319 void runPendingTasks() |
| 320 { |
| 321 m_platform->runPendingTasks(); |
| 322 } |
| 323 |
301 void runUntilIdleOrDeadlinePassed(double deadline) | 324 void runUntilIdleOrDeadlinePassed(double deadline) |
302 { | 325 { |
303 m_platform->runUntilIdleOrDeadlinePassed(deadline); | 326 m_platform->runUntilIdleOrDeadlinePassed(deadline); |
304 } | 327 } |
305 | 328 |
306 bool hasOneTimerTask() const | 329 bool hasOneTimerTask() const |
307 { | 330 { |
308 return m_platform->hasOneTimerTask(); | 331 return m_platform->hasOneTimerTask(); |
309 } | 332 } |
310 | 333 |
311 long nextTimerTaskDelayMillis() const | 334 double nextTimerTaskDelaySecs() const |
312 { | 335 { |
313 return m_platform->nextTimerTaskDelayMillis(); | 336 return m_platform->nextTimerTaskDelaySecs(); |
314 } | 337 } |
315 | 338 |
316 protected: | 339 protected: |
317 double m_startTime; | 340 double m_startTime; |
| 341 // TODO(alexclarke): Migrate to WTF::Vector and add gmock matcher support. |
318 std::vector<double> m_runTimes; | 342 std::vector<double> m_runTimes; |
| 343 std::vector<double> m_nextFireTimes; |
319 | 344 |
320 private: | 345 private: |
321 OwnPtr<TimerTestPlatform> m_platform; | 346 OwnPtr<TimerTestPlatform> m_platform; |
322 Platform* m_oldPlatform; | 347 Platform* m_oldPlatform; |
323 }; | 348 }; |
324 | 349 |
325 TEST_F(TimerTest, StartOneShot_Zero) | 350 TEST_F(TimerTest, StartOneShot_Zero) |
326 { | 351 { |
327 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 352 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
328 timer.startOneShot(0, FROM_HERE); | 353 timer.startOneShot(0, FROM_HERE); |
329 | 354 |
330 ASSERT(hasOneTimerTask()); | 355 ASSERT(hasOneTimerTask()); |
331 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 356 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
332 | 357 |
333 runUntilIdle(); | 358 runUntilIdle(); |
334 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); | 359 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
335 } | 360 } |
336 | 361 |
337 TEST_F(TimerTest, StartOneShot_ZeroAndCancel) | 362 TEST_F(TimerTest, StartOneShot_ZeroAndCancel) |
338 { | 363 { |
339 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 364 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
340 timer.startOneShot(0, FROM_HERE); | 365 timer.startOneShot(0, FROM_HERE); |
341 | 366 |
342 ASSERT(hasOneTimerTask()); | 367 ASSERT(hasOneTimerTask()); |
343 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 368 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
344 | 369 |
345 timer.stop(); | 370 timer.stop(); |
346 | 371 |
347 runUntilIdle(); | 372 runUntilIdle(); |
348 EXPECT_TRUE(m_runTimes.empty()); | 373 EXPECT_TRUE(m_runTimes.empty()); |
349 } | 374 } |
350 | 375 |
351 TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) | 376 TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) |
352 { | 377 { |
353 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 378 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
354 timer.startOneShot(0, FROM_HERE); | 379 timer.startOneShot(0, FROM_HERE); |
355 | 380 |
356 ASSERT(hasOneTimerTask()); | 381 ASSERT(hasOneTimerTask()); |
357 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 382 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
358 | 383 |
359 timer.stop(); | 384 timer.stop(); |
360 | 385 |
361 runUntilIdle(); | 386 runUntilIdle(); |
362 EXPECT_TRUE(m_runTimes.empty()); | 387 EXPECT_TRUE(m_runTimes.empty()); |
363 | 388 |
364 timer.startOneShot(0, FROM_HERE); | 389 timer.startOneShot(0, FROM_HERE); |
365 | 390 |
366 ASSERT(hasOneTimerTask()); | 391 ASSERT(hasOneTimerTask()); |
367 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 392 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
368 | 393 |
369 runUntilIdle(); | 394 runUntilIdle(); |
370 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); | 395 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
371 } | 396 } |
372 | 397 |
373 TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) | 398 TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) |
374 { | 399 { |
375 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 400 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
376 timer.startOneShot(0, FROM_HERE); | 401 timer.startOneShot(0, FROM_HERE); |
377 | 402 |
378 ASSERT(hasOneTimerTask()); | 403 ASSERT(hasOneTimerTask()); |
379 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 404 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
380 | 405 |
381 runUntilIdle(); | 406 runUntilIdle(); |
382 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); | 407 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime)); |
383 | 408 |
384 timer.startOneShot(0, FROM_HERE); | 409 timer.startOneShot(0, FROM_HERE); |
385 | 410 |
386 ASSERT(hasOneTimerTask()); | 411 ASSERT(hasOneTimerTask()); |
387 EXPECT_EQ(0ll, nextTimerTaskDelayMillis()); | 412 EXPECT_FLOAT_EQ(0.0, nextTimerTaskDelaySecs()); |
388 | 413 |
389 runUntilIdle(); | 414 runUntilIdle(); |
390 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime, m_startTime)); | 415 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime, m_startTime)); |
391 } | 416 } |
392 | 417 |
393 TEST_F(TimerTest, StartOneShot_NonZero) | 418 TEST_F(TimerTest, StartOneShot_NonZero) |
394 { | 419 { |
395 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 420 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
396 timer.startOneShot(10.0, FROM_HERE); | 421 timer.startOneShot(10.0, FROM_HERE); |
397 | 422 |
398 ASSERT(hasOneTimerTask()); | 423 ASSERT(hasOneTimerTask()); |
399 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 424 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
400 | 425 |
401 runUntilIdle(); | 426 runUntilIdle(); |
402 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); | 427 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
403 } | 428 } |
404 | 429 |
405 TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) | 430 TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) |
406 { | 431 { |
407 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 432 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
408 timer.startOneShot(10, FROM_HERE); | 433 timer.startOneShot(10, FROM_HERE); |
409 | 434 |
410 ASSERT(hasOneTimerTask()); | 435 ASSERT(hasOneTimerTask()); |
411 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 436 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
412 | 437 |
413 timer.stop(); | 438 timer.stop(); |
414 | 439 |
415 runUntilIdle(); | 440 runUntilIdle(); |
416 EXPECT_TRUE(m_runTimes.empty()); | 441 EXPECT_TRUE(m_runTimes.empty()); |
417 } | 442 } |
418 | 443 |
419 TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) | 444 TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) |
420 { | 445 { |
421 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 446 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
422 timer.startOneShot(10, FROM_HERE); | 447 timer.startOneShot(10, FROM_HERE); |
423 | 448 |
424 ASSERT(hasOneTimerTask()); | 449 ASSERT(hasOneTimerTask()); |
425 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 450 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
426 | 451 |
427 timer.stop(); | 452 timer.stop(); |
428 | 453 |
429 runUntilIdle(); | 454 runUntilIdle(); |
430 EXPECT_TRUE(m_runTimes.empty()); | 455 EXPECT_TRUE(m_runTimes.empty()); |
431 | 456 |
432 double secondPostTime = monotonicallyIncreasingTime(); | 457 double secondPostTime = monotonicallyIncreasingTime(); |
433 timer.startOneShot(10, FROM_HERE); | 458 timer.startOneShot(10, FROM_HERE); |
434 | 459 |
435 ASSERT(hasOneTimerTask()); | 460 ASSERT(hasOneTimerTask()); |
436 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 461 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
437 | 462 |
438 runUntilIdle(); | 463 runUntilIdle(); |
439 EXPECT_THAT(m_runTimes, ElementsAre(secondPostTime + 10.0)); | 464 EXPECT_THAT(m_runTimes, ElementsAre(secondPostTime + 10.0)); |
440 } | 465 } |
441 | 466 |
442 TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) | 467 TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) |
443 { | 468 { |
444 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 469 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
445 timer.startOneShot(10, FROM_HERE); | 470 timer.startOneShot(10, FROM_HERE); |
446 | 471 |
447 ASSERT(hasOneTimerTask()); | 472 ASSERT(hasOneTimerTask()); |
448 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 473 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
449 | 474 |
450 runUntilIdle(); | 475 runUntilIdle(); |
451 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); | 476 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
452 | 477 |
453 timer.startOneShot(20, FROM_HERE); | 478 timer.startOneShot(20, FROM_HERE); |
454 | 479 |
455 ASSERT(hasOneTimerTask()); | 480 ASSERT(hasOneTimerTask()); |
456 EXPECT_EQ(20000ll, nextTimerTaskDelayMillis()); | 481 EXPECT_FLOAT_EQ(20.0, nextTimerTaskDelaySecs()); |
457 | 482 |
458 runUntilIdle(); | 483 runUntilIdle(); |
459 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0, m_startTime + 30.0))
; | 484 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0, m_startTime + 30.0))
; |
460 } | 485 } |
461 | 486 |
462 TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) | 487 TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) |
463 { | 488 { |
464 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 489 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
465 timer.startOneShot(10, FROM_HERE); | 490 timer.startOneShot(10, FROM_HERE); |
466 timer.startOneShot(10, FROM_HERE); | 491 timer.startOneShot(10, FROM_HERE); |
467 | 492 |
468 ASSERT(hasOneTimerTask()); | 493 ASSERT(hasOneTimerTask()); |
469 EXPECT_EQ(10000ll, nextTimerTaskDelayMillis()); | 494 EXPECT_FLOAT_EQ(10.0, nextTimerTaskDelaySecs()); |
470 | 495 |
471 runUntilIdle(); | 496 runUntilIdle(); |
472 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); | 497 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
473 } | 498 } |
474 | 499 |
475 TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) | 500 TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) |
476 { | 501 { |
477 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 502 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
478 timer.startOneShot(10, FROM_HERE); | 503 timer.startOneShot(10, FROM_HERE); |
479 timer.startOneShot(0, FROM_HERE); | 504 timer.startOneShot(0, FROM_HERE); |
(...skipping 11 matching lines...) Expand all Loading... |
491 runUntilIdle(); | 516 runUntilIdle(); |
492 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); | 517 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 10.0)); |
493 } | 518 } |
494 | 519 |
495 TEST_F(TimerTest, StartRepeatingTask) | 520 TEST_F(TimerTest, StartRepeatingTask) |
496 { | 521 { |
497 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 522 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
498 timer.startRepeating(1.0, FROM_HERE); | 523 timer.startRepeating(1.0, FROM_HERE); |
499 | 524 |
500 ASSERT(hasOneTimerTask()); | 525 ASSERT(hasOneTimerTask()); |
501 EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); | 526 EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
502 | 527 |
503 runUntilIdleOrDeadlinePassed(m_startTime + 5.5); | 528 runUntilIdleOrDeadlinePassed(m_startTime + 5.5); |
504 EXPECT_THAT(m_runTimes, ElementsAre( | 529 EXPECT_THAT(m_runTimes, ElementsAre( |
505 m_startTime + 1.0, m_startTime + 2.0, m_startTime + 3.0, m_startTime + 4
.0, m_startTime + 5.0)); | 530 m_startTime + 1.0, m_startTime + 2.0, m_startTime + 3.0, m_startTime + 4
.0, m_startTime + 5.0)); |
506 } | 531 } |
507 | 532 |
508 TEST_F(TimerTest, StartRepeatingTask_ThenCancel) | 533 TEST_F(TimerTest, StartRepeatingTask_ThenCancel) |
509 { | 534 { |
510 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 535 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
511 timer.startRepeating(1.0, FROM_HERE); | 536 timer.startRepeating(1.0, FROM_HERE); |
512 | 537 |
513 ASSERT(hasOneTimerTask()); | 538 ASSERT(hasOneTimerTask()); |
514 EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); | 539 EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
515 | 540 |
516 runUntilIdleOrDeadlinePassed(m_startTime + 2.5); | 541 runUntilIdleOrDeadlinePassed(m_startTime + 2.5); |
517 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); | 542 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); |
518 | 543 |
519 timer.stop(); | 544 timer.stop(); |
520 runUntilIdle(); | 545 runUntilIdle(); |
521 | 546 |
522 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); | 547 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); |
523 } | 548 } |
524 | 549 |
525 TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) | 550 TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) |
526 { | 551 { |
527 Timer<TimerTest> timer(this, &TimerTest::countingTask); | 552 Timer<TimerTest> timer(this, &TimerTest::countingTask); |
528 timer.startRepeating(1.0, FROM_HERE); | 553 timer.startRepeating(1.0, FROM_HERE); |
529 | 554 |
530 ASSERT(hasOneTimerTask()); | 555 ASSERT(hasOneTimerTask()); |
531 EXPECT_EQ(1000ll, nextTimerTaskDelayMillis()); | 556 EXPECT_FLOAT_EQ(1.0, nextTimerTaskDelaySecs()); |
532 | 557 |
533 runUntilIdleOrDeadlinePassed(m_startTime + 2.5); | 558 runUntilIdleOrDeadlinePassed(m_startTime + 2.5); |
534 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); | 559 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0)); |
535 | 560 |
536 timer.startOneShot(0, FROM_HERE); | 561 timer.startOneShot(0, FROM_HERE); |
537 runUntilIdle(); | 562 runUntilIdle(); |
538 | 563 |
539 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0, m_
startTime + 2.5)); | 564 EXPECT_THAT(m_runTimes, ElementsAre(m_startTime + 1.0, m_startTime + 2.0, m_
startTime + 2.5)); |
540 } | 565 } |
541 | 566 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); | 770 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); |
746 | 771 |
747 timer.setAlignedFireTime(m_startTime); | 772 timer.setAlignedFireTime(m_startTime); |
748 timer.didChangeAlignmentInterval(monotonicallyIncreasingTime()); | 773 timer.didChangeAlignmentInterval(monotonicallyIncreasingTime()); |
749 | 774 |
750 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval()); | 775 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval()); |
751 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); | 776 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); |
752 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); | 777 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); |
753 } | 778 } |
754 | 779 |
| 780 TEST_F(TimerTest, RepeatingTimerDoesNotDrift) |
| 781 { |
| 782 Timer<TimerTest> timer(this, &TimerTest::recordNextFireTimeTask); |
| 783 timer.startRepeating(2.0, FROM_HERE); |
| 784 |
| 785 ASSERT(hasOneTimerTask()); |
| 786 recordNextFireTimeTask(&timer); // Next scheduled task to run at m_startTime
+ 2.0 |
| 787 |
| 788 // Simulate timer firing early. Next scheduled task to run at m_startTime +
4.0 |
| 789 advanceTimeBy(1.9); |
| 790 runUntilIdleOrDeadlinePassed(gCurrentTimeSecs + 0.2); |
| 791 |
| 792 advanceTimeBy(2.0); |
| 793 runPendingTasks(); // Next scheduled task to run at m_startTime + 6.0 |
| 794 |
| 795 advanceTimeBy(2.1); |
| 796 runPendingTasks(); // Next scheduled task to run at m_startTime + 8.0 |
| 797 |
| 798 advanceTimeBy(2.9); |
| 799 runPendingTasks(); // Next scheduled task to run at m_startTime + 10.0 |
| 800 |
| 801 advanceTimeBy(3.1); |
| 802 runPendingTasks(); // Next scheduled task to run at m_startTime + 14.0 (skip
s a beat) |
| 803 |
| 804 advanceTimeBy(4.0); |
| 805 runPendingTasks(); // Next scheduled task to run at m_startTime + 18.0 (skip
s a beat) |
| 806 |
| 807 advanceTimeBy(10.0); // Next scheduled task to run at m_startTime + 28.0 (sk
ips 5 beats) |
| 808 runPendingTasks(); |
| 809 |
| 810 runUntilIdleOrDeadlinePassed(m_startTime + 5.5); |
| 811 EXPECT_THAT(m_nextFireTimes, ElementsAre( |
| 812 m_startTime + 2.0, |
| 813 m_startTime + 4.0, |
| 814 m_startTime + 6.0, |
| 815 m_startTime + 8.0, |
| 816 m_startTime + 10.0, |
| 817 m_startTime + 14.0, |
| 818 m_startTime + 18.0, |
| 819 m_startTime + 28.0)); |
| 820 } |
755 | 821 |
756 } // namespace | 822 } // namespace |
757 } // namespace blink | 823 } // namespace blink |
OLD | NEW |