fixing flaky macos timing tests

This commit is contained in:
matlabbe
2026-05-17 15:05:00 -07:00
parent 417f9aa494
commit 30605f690d
+40 -26
View File
@@ -3,6 +3,20 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
namespace {
// Requested sleep durations (seconds)
constexpr double kSleep10Ms = 0.01;
constexpr double kSleep20Ms = 0.02;
constexpr double kSleep5Ms = 0.005;
// Upper bounds: macOS/CI runners often wake threads much later than requested
constexpr double kMaxSlack10Ms = 0.25;
constexpr double kMaxSlack20Ms = 0.40;
constexpr double kMaxSlack5Ms = 0.15;
} // namespace
TEST(UTimerTest, Constructor) TEST(UTimerTest, Constructor)
{ {
UTimer timer; UTimer timer;
@@ -17,8 +31,8 @@ TEST(UTimerTest, StartStop)
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
timer.stop(); timer.stop();
double elapsed = timer.getElapsedTime(); double elapsed = timer.getElapsedTime();
EXPECT_GE(elapsed, 0.01); // Should be at least 10 ms EXPECT_GE(elapsed, kSleep10Ms);
EXPECT_LT(elapsed, 0.015); // Should be less than 15 ms EXPECT_LT(elapsed, kMaxSlack10Ms);
} }
TEST(UTimerTest, Elapsed) TEST(UTimerTest, Elapsed)
@@ -27,14 +41,14 @@ TEST(UTimerTest, Elapsed)
timer.start(); timer.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double elapsed = timer.elapsed(); double elapsed = timer.elapsed();
EXPECT_GE(elapsed, 0.01); EXPECT_GE(elapsed, kSleep10Ms);
EXPECT_LT(elapsed, 0.015); EXPECT_LT(elapsed, kMaxSlack10Ms);
// Timer should still be running after elapsed() // Timer should still be running after elapsed()
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double ticks2 = timer.ticks(); double ticks2 = timer.ticks();
EXPECT_GE(ticks2, 0.02); EXPECT_GE(ticks2, kSleep20Ms);
EXPECT_LT(ticks2, 0.025); EXPECT_LT(ticks2, kMaxSlack20Ms);
} }
TEST(UTimerTest, GetElapsedTime) TEST(UTimerTest, GetElapsedTime)
@@ -43,14 +57,14 @@ TEST(UTimerTest, GetElapsedTime)
timer.start(); timer.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double elapsed = timer.getElapsedTime(); double elapsed = timer.getElapsedTime();
EXPECT_GE(elapsed, 0.01); EXPECT_GE(elapsed, kSleep10Ms);
EXPECT_LT(elapsed, 0.015); EXPECT_LT(elapsed, kMaxSlack10Ms);
// Timer should still be running after getElapsedTime() // Timer should still be running after getElapsedTime()
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double ticks2 = timer.ticks(); double ticks2 = timer.ticks();
EXPECT_GE(ticks2, 0.02); EXPECT_GE(ticks2, kSleep20Ms);
EXPECT_LT(ticks2, 0.025); EXPECT_LT(ticks2, kMaxSlack20Ms);
} }
TEST(UTimerTest, Ticks) TEST(UTimerTest, Ticks)
@@ -59,14 +73,14 @@ TEST(UTimerTest, Ticks)
timer.start(); timer.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double ticks1 = timer.ticks(); double ticks1 = timer.ticks();
EXPECT_GE(ticks1, 0.01); EXPECT_GE(ticks1, kSleep10Ms);
EXPECT_LT(ticks1, 0.015); EXPECT_LT(ticks1, kMaxSlack10Ms);
// Timer should have retarted and still be running after ticks() // Timer should have retarted and still be running after ticks()
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double ticks2 = timer.ticks(); double ticks2 = timer.ticks();
EXPECT_GE(ticks2, 0.01); EXPECT_GE(ticks2, kSleep10Ms);
EXPECT_LT(ticks2, 0.015); EXPECT_LT(ticks2, kMaxSlack10Ms);
} }
TEST(UTimerTest, Restart) TEST(UTimerTest, Restart)
@@ -75,14 +89,14 @@ TEST(UTimerTest, Restart)
timer.start(); timer.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double elapsed1 = timer.restart(); double elapsed1 = timer.restart();
EXPECT_GE(elapsed1, 0.01); EXPECT_GE(elapsed1, kSleep10Ms);
EXPECT_LT(elapsed1, 0.02); EXPECT_LT(elapsed1, kMaxSlack10Ms);
// After restart, timer should be running again // After restart, timer should be running again
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double elapsed2 = timer.elapsed(); double elapsed2 = timer.elapsed();
EXPECT_GE(elapsed2, 0.01); EXPECT_GE(elapsed2, kSleep10Ms);
EXPECT_LT(elapsed2, 0.02); EXPECT_LT(elapsed2, kMaxSlack10Ms);
} }
TEST(UTimerTest, Now) TEST(UTimerTest, Now)
@@ -90,8 +104,8 @@ TEST(UTimerTest, Now)
double time1 = UTimer::now(); double time1 = UTimer::now();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
double time2 = UTimer::now(); double time2 = UTimer::now();
EXPECT_GE(time2-time1, 0.01); EXPECT_GE(time2-time1, kSleep10Ms);
EXPECT_LT(time2-time1, 0.015); EXPECT_LT(time2-time1, kMaxSlack10Ms);
} }
TEST(UTimerTest, MultipleStartStop) TEST(UTimerTest, MultipleStartStop)
@@ -107,9 +121,9 @@ TEST(UTimerTest, MultipleStartStop)
timer.stop(); timer.stop();
double elapsed2 = timer.getElapsedTime(); double elapsed2 = timer.getElapsedTime();
EXPECT_GE(elapsed1, 0.005); EXPECT_GE(elapsed1, kSleep5Ms);
EXPECT_LT(elapsed1, 0.01); EXPECT_LT(elapsed1, kMaxSlack5Ms);
EXPECT_GE(elapsed2, 0.005); EXPECT_GE(elapsed2, kSleep5Ms);
EXPECT_LT(elapsed2, 0.01); EXPECT_LT(elapsed2, kMaxSlack5Ms);
} }