|
10 | 10 |
|
11 | 11 | #include "test/mocks/common.h" |
12 | 12 | #include "test/mocks/stats/mocks.h" |
| 13 | +#include "test/test_common/simulated_time_system.h" |
13 | 14 | #include "test/test_common/utility.h" |
14 | 15 |
|
15 | 16 | #include "gmock/gmock.h" |
@@ -315,6 +316,52 @@ TEST(TimerImplTest, TimerEnabledDisabled) { |
315 | 316 | EXPECT_FALSE(timer->enabled()); |
316 | 317 | } |
317 | 318 |
|
| 319 | +class TimerImplTimingTest : public testing::Test { |
| 320 | +public: |
| 321 | + std::chrono::nanoseconds getTimerTiming(Event::SimulatedTimeSystem& time_system, |
| 322 | + Dispatcher& dispatcher, Event::Timer& timer) { |
| 323 | + const auto start = time_system.monotonicTime(); |
| 324 | + EXPECT_TRUE(timer.enabled()); |
| 325 | + while (true) { |
| 326 | + dispatcher.run(Dispatcher::RunType::NonBlock); |
| 327 | + if (timer.enabled()) { |
| 328 | + time_system.sleep(std::chrono::microseconds(1)); |
| 329 | + } else { |
| 330 | + break; |
| 331 | + } |
| 332 | + } |
| 333 | + return time_system.monotonicTime() - start; |
| 334 | + } |
| 335 | +}; |
| 336 | + |
| 337 | +// Test the timer with a series of timings and measure they fire accurately |
| 338 | +// using simulated time. enableTimer() should be precise at the millisecond |
| 339 | +// level, whereas enableHRTimer should be precise at the microsecond level. |
| 340 | +// For good measure, also check that '0'/immediate does what it says on the tin. |
| 341 | +TEST_F(TimerImplTimingTest, TheoreticalTimerTiming) { |
| 342 | + Event::SimulatedTimeSystem time_system; |
| 343 | + Api::ApiPtr api = Api::createApiForTest(time_system); |
| 344 | + DispatcherPtr dispatcher(api->allocateDispatcher()); |
| 345 | + Event::TimerPtr timer = dispatcher->createTimer([&dispatcher] { dispatcher->exit(); }); |
| 346 | + |
| 347 | + const uint64_t timings[] = {0, 10, 50, 1234}; |
| 348 | + for (const uint64_t timing : timings) { |
| 349 | + std::chrono::milliseconds ms(timing); |
| 350 | + timer->enableTimer(ms); |
| 351 | + EXPECT_EQ(std::chrono::duration_cast<std::chrono::milliseconds>( |
| 352 | + getTimerTiming(time_system, *dispatcher, *timer)) |
| 353 | + .count(), |
| 354 | + timing); |
| 355 | + |
| 356 | + std::chrono::microseconds us(timing); |
| 357 | + timer->enableHRTimer(us); |
| 358 | + EXPECT_EQ(std::chrono::duration_cast<std::chrono::microseconds>( |
| 359 | + getTimerTiming(time_system, *dispatcher, *timer)) |
| 360 | + .count(), |
| 361 | + timing); |
| 362 | + } |
| 363 | +} |
| 364 | + |
318 | 365 | TEST(TimerImplTest, TimerValueConversion) { |
319 | 366 | timeval tv; |
320 | 367 | std::chrono::milliseconds msecs; |
|
0 commit comments