summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksim Skurydzin <maksim.skurydzin@mapbox.com>2019-09-12 19:35:51 +0300
committerMaksim Skurydzin <maksim.skurydzin@mapbox.com>2019-09-19 14:35:52 +0300
commit007e856b0578aa54ee8a400fc267b4f2dd197169 (patch)
tree63038adc955330e021569785442cb0ab74cd7182
parent80e8d7a2fcb9f75e585bb7dd26c2f2a893b6f560 (diff)
downloadqtlocation-mapboxgl-upstream/pr-15621.tar.gz
[test] Add unit tests for mbgl::util::Timer covering timer cancellation at/after its expirationupstream/pr-15621upstream/ms-more-unit-tests-for-timer
-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;