forked from UBC-Thunderbots/Software
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix flaky Observer tests using fake clock (UBC-Thunderbots#3318)
* Fix observer test flakiness using FakeClock * Add FakeClock unit tests * Run formatting * Use using instead of typedef * [pre-commit.ci lite] apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
- Loading branch information
Showing
7 changed files
with
151 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include "fake_clock.h" | ||
|
||
FakeClock::time_point FakeClock::now_; | ||
|
||
FakeClock::time_point FakeClock::now() noexcept | ||
{ | ||
return now_; | ||
} | ||
|
||
void FakeClock::advance(duration time) noexcept | ||
{ | ||
now_ += time; | ||
} | ||
|
||
void FakeClock::reset() noexcept | ||
{ | ||
now_ = FakeClock::time_point(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#pragma once | ||
|
||
#include <chrono> | ||
#include <cstdint> | ||
#include <ratio> | ||
|
||
/** | ||
* Fake clock convenient for testing purposes. | ||
* | ||
* Tests that rely on sleeping can be non-deterministic and flaky since they | ||
* depend on real time to elapse. Use this clock instead, which can be explicitly | ||
* advanced without sleeping. | ||
* | ||
* Satisfies the TrivialClock requirements and thus can replace any standard clock | ||
* in the chrono library (e.g. std::chrono::steady_clock). | ||
*/ | ||
class FakeClock | ||
{ | ||
public: | ||
using rep = uint64_t; | ||
using period = std::nano; | ||
using duration = std::chrono::duration<rep, period>; | ||
using time_point = std::chrono::time_point<FakeClock>; | ||
inline static const bool is_steady = false; | ||
|
||
/** | ||
* Returns the current time point. | ||
* | ||
* @return the current time point | ||
*/ | ||
static time_point now() noexcept; | ||
|
||
/** | ||
* Advances the current time point by the given amount of time. | ||
* | ||
* @param time the amount of time to advance the current time point by | ||
*/ | ||
static void advance(duration time) noexcept; | ||
|
||
/** | ||
* Resets the current time point to the clock's epoch | ||
* (the origin of fake_clock::time_point) | ||
*/ | ||
static void reset() noexcept; | ||
|
||
private: | ||
FakeClock() = delete; | ||
~FakeClock() = delete; | ||
FakeClock(FakeClock const&) = delete; | ||
|
||
static time_point now_; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include "software/test_util/fake_clock.h" | ||
|
||
#include <gtest/gtest.h> | ||
|
||
TEST(FakeClockTest, time_point_now_should_not_change_without_advancing) | ||
{ | ||
FakeClock::reset(); | ||
FakeClock::time_point t0 = FakeClock::now(); | ||
FakeClock::time_point t1 = FakeClock::now(); | ||
EXPECT_EQ(std::chrono::milliseconds(0), t1 - t0); | ||
} | ||
|
||
TEST(FakeClockTest, time_point_now_should_move_forward_after_advancing) | ||
{ | ||
FakeClock::reset(); | ||
FakeClock::time_point t0 = FakeClock::now(); | ||
|
||
FakeClock::advance(std::chrono::milliseconds(100)); | ||
FakeClock::time_point t1 = FakeClock::now(); | ||
EXPECT_EQ(std::chrono::milliseconds(100), t1 - t0); | ||
|
||
FakeClock::advance(std::chrono::milliseconds(50)); | ||
FakeClock::time_point t2 = FakeClock::now(); | ||
EXPECT_EQ(std::chrono::milliseconds(150), t2 - t0); | ||
} | ||
|
||
TEST(FakeClockTest, reset_should_set_time_point_now_to_clock_epoch) | ||
{ | ||
FakeClock::reset(); | ||
FakeClock::time_point t0 = FakeClock::now(); | ||
|
||
FakeClock::advance(std::chrono::milliseconds(1000)); | ||
FakeClock::time_point t1 = FakeClock::now(); | ||
EXPECT_EQ(std::chrono::milliseconds(1000), t1 - t0); | ||
|
||
FakeClock::reset(); | ||
FakeClock::time_point t2 = FakeClock::now(); | ||
EXPECT_EQ(std::chrono::milliseconds(0), t2 - t0); | ||
} |