File tree Expand file tree Collapse file tree 2 files changed +50
-0
lines changed
Expand file tree Collapse file tree 2 files changed +50
-0
lines changed Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread
2121
2222static std::atomic<std::chrono::seconds> g_mock_time{}; // !< For testing
2323std::atomic<bool > g_used_system_time{false };
24+ static std::atomic<std::chrono::milliseconds> g_mock_steady_time{}; // !< For testing
2425
2526NodeClock::time_point NodeClock::now () noexcept
2627{
@@ -48,6 +49,30 @@ std::chrono::seconds GetMockTime()
4849 return g_mock_time.load (std::memory_order_relaxed);
4950}
5051
52+ MockableSteadyClock::time_point MockableSteadyClock::now () noexcept
53+ {
54+ const auto mocktime{g_mock_steady_time.load (std::memory_order_relaxed)};
55+ if (!mocktime.count ()) {
56+ g_used_system_time = true ;
57+ }
58+ const auto ret{
59+ mocktime.count () ?
60+ mocktime :
61+ std::chrono::steady_clock::now ().time_since_epoch ()};
62+ return time_point{ret};
63+ };
64+
65+ void MockableSteadyClock::SetMockTime (std::chrono::milliseconds mock_time_in)
66+ {
67+ Assert (mock_time_in >= 0s);
68+ g_mock_steady_time.store (mock_time_in, std::memory_order_relaxed);
69+ }
70+
71+ void MockableSteadyClock::ClearMockTime ()
72+ {
73+ g_mock_steady_time.store (0ms, std::memory_order_relaxed);
74+ }
75+
5176int64_t GetTime () { return GetTime<std::chrono::seconds>().count (); }
5277
5378std::string FormatISO8601DateTime (int64_t nTime)
Original file line number Diff line number Diff line change @@ -31,6 +31,31 @@ using SteadyMicroseconds = std::chrono::time_point<std::chrono::steady_clock, st
3131
3232using SystemClock = std::chrono::system_clock;
3333
34+ /* *
35+ * Version of SteadyClock that is mockable in the context of tests (set the
36+ * current value with SetMockTime), otherwise the system steady clock.
37+ */
38+ struct MockableSteadyClock : public std ::chrono::steady_clock {
39+ using time_point = std::chrono::time_point<MockableSteadyClock>;
40+
41+ static constexpr std::chrono::milliseconds INITIAL_MOCK_TIME{1 };
42+
43+ /* * Return current system time or mocked time, if set */
44+ static time_point now () noexcept ;
45+ static std::time_t to_time_t (const time_point&) = delete; // unused
46+ static time_point from_time_t (std::time_t ) = delete; // unused
47+
48+ /* * Set mock time for testing.
49+ * When mocking the steady clock, start at INITIAL_MOCK_TIME and add durations to elapse time as necessary
50+ * for testing.
51+ * To stop mocking, call ClearMockTime().
52+ */
53+ static void SetMockTime (std::chrono::milliseconds mock_time_in);
54+
55+ /* * Clear mock time, go back to system steady clock. */
56+ static void ClearMockTime ();
57+ };
58+
3459void UninterruptibleSleep (const std::chrono::microseconds& n);
3560
3661/* *
You can’t perform that action at this time.
0 commit comments