summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMaksim Skurydzin <maksim.skurydzin@mapbox.com>2019-09-19 19:55:00 +0300
committerGitHub <noreply@github.com>2019-09-19 19:55:00 +0300
commitc7737fe87707be9a9349e04170ca18781cdb4037 (patch)
tree0111822eecdd28cb3d74f5ecefc6247d1cd85e8b /test
parent097cf5fc3993c23c6d81f16df9d9040d540dbb21 (diff)
downloadqtlocation-mapboxgl-c7737fe87707be9a9349e04170ca18781cdb4037.tar.gz
[test] Add unit tests for mbgl::util::Timer covering timer cancellation at/after its expiration (#15621)
Diffstat (limited to 'test')
-rw-r--r--test/util/timer.test.cpp68
1 files changed, 67 insertions, 1 deletions
diff --git a/test/util/timer.test.cpp b/test/util/timer.test.cpp
index f6253ab6d3..20bdc3c599 100644
--- a/test/util/timer.test.cpp
+++ b/test/util/timer.test.cpp
@@ -3,7 +3,6 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/timer.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <mbgl/util/chrono.hpp>
#include <memory>
@@ -131,6 +130,73 @@ TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(DestroyShouldStop)) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
+TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(StoppedDuringExpiration)) {
+ // The idea is to have original timer cancellation and expiration roughly at the same time.
+ // In this case some timer backens (e.g. asio::high_resolution_timer)
+ // may call the expiration callback with good status while the timer may not expect it.
+
+ RunLoop loop;
+
+ auto timer = std::make_unique<Timer>();
+ auto loopStopTimer = std::make_unique<Timer>();
+ auto expireTimeout = mbgl::Milliseconds(50);
+
+ auto timerCallback = [&] {
+ // we cannot expect much here as in some cases timer may be finished earlier
+ // than the loop stop timer (and thus the callback will be called)
+ };
+
+ auto loopStopTimerCallback = [&] {
+ timer->stop();
+ loop.stop();
+ };
+
+ auto first = mbgl::Clock::now();
+
+ loopStopTimer->start(expireTimeout, mbgl::Milliseconds(0), loopStopTimerCallback);
+ timer->start(expireTimeout, mbgl::Milliseconds(0), timerCallback);
+
+ loop.run();
+
+ auto totalTime = std::chrono::duration_cast<mbgl::Milliseconds>(mbgl::Clock::now() - first);
+
+ EXPECT_GE(totalTime, expireTimeout * 0.8);
+ EXPECT_LE(totalTime, expireTimeout * 1.2);
+}
+
+TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(StoppedAfterExpiration)) {
+ RunLoop loop;
+
+ auto timer = std::make_unique<Timer>();
+ auto loopStopTimer = std::make_unique<Timer>();
+ auto expireTimeout = mbgl::Milliseconds(50);
+
+ bool callbackFired = false;
+
+ auto timerCallback = [&] { callbackFired = true; };
+
+ auto first = mbgl::Clock::now();
+
+ timer->start(expireTimeout, mbgl::Milliseconds(0), timerCallback);
+
+ // poll until the timer expires
+ auto expireWaitInterval = expireTimeout * 2;
+ auto startWaitTime = mbgl::Clock::now();
+ auto waitDuration = mbgl::Duration::zero();
+ while (waitDuration < expireWaitInterval) {
+ waitDuration = std::chrono::duration_cast<mbgl::Milliseconds>(mbgl::Clock::now() - startWaitTime);
+ }
+ timer->stop();
+
+ loop.runOnce();
+
+ auto totalTime = std::chrono::duration_cast<mbgl::Milliseconds>(mbgl::Clock::now() - first);
+
+ EXPECT_TRUE(!callbackFired);
+ EXPECT_GE(totalTime, expireWaitInterval * 0.8);
+ EXPECT_LE(totalTime, expireWaitInterval * 1.2);
+}
+
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(StartOverrides)) {
RunLoop loop;