mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Actually make monotonic time functions mockable.
This is different from making the functions mockable, since monotime_t is opaque and so providing mocks for the functions is really hard.
This commit is contained in:
parent
72a1f0180d
commit
2d26b1a549
@ -118,6 +118,74 @@ tor_gettimeofday(struct timeval *timeval)
|
|||||||
/** True iff monotime_init has been called. */
|
/** True iff monotime_init has been called. */
|
||||||
static int monotime_initialized = 0;
|
static int monotime_initialized = 0;
|
||||||
|
|
||||||
|
static monotime_t initialized_at;
|
||||||
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
|
static monotime_coarse_t initialized_at_coarse;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
/** True if we are running unit tests and overriding the current monotonic
|
||||||
|
* time. Note that mocked monotonic time might not be monotonic.
|
||||||
|
*/
|
||||||
|
static int monotime_mocking_enabled = 0;
|
||||||
|
static monotime_t initialized_at_saved;
|
||||||
|
|
||||||
|
static int64_t mock_time_nsec = 0;
|
||||||
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
|
static int64_t mock_time_nsec_coarse = 0;
|
||||||
|
static monotime_coarse_t initialized_at_coarse_saved;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
monotime_enable_test_mocking(void)
|
||||||
|
{
|
||||||
|
if (BUG(monotime_initialized == 0)) {
|
||||||
|
monotime_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
tor_assert_nonfatal(monotime_mocking_enabled == 0);
|
||||||
|
monotime_mocking_enabled = 1;
|
||||||
|
memcpy(&initialized_at_saved,
|
||||||
|
&initialized_at, sizeof(monotime_t));
|
||||||
|
memset(&initialized_at, 0, sizeof(monotime_t));
|
||||||
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
|
memcpy(&initialized_at_coarse_saved,
|
||||||
|
&initialized_at_coarse, sizeof(monotime_coarse_t));
|
||||||
|
memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
monotime_disable_test_mocking(void)
|
||||||
|
{
|
||||||
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
||||||
|
monotime_mocking_enabled = 0;
|
||||||
|
|
||||||
|
memcpy(&initialized_at,
|
||||||
|
&initialized_at_saved, sizeof(monotime_t));
|
||||||
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
|
memcpy(&initialized_at_coarse,
|
||||||
|
&initialized_at_coarse_saved, sizeof(monotime_coarse_t));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
monotime_set_mock_time_nsec(int64_t nsec)
|
||||||
|
{
|
||||||
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
||||||
|
mock_time_nsec = nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
|
void
|
||||||
|
monotime_coarse_set_mock_time_nsec(int64_t nsec)
|
||||||
|
{
|
||||||
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
||||||
|
mock_time_nsec_coarse = nsec;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* "ratchet" functions for monotonic time. */
|
/* "ratchet" functions for monotonic time. */
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
||||||
@ -223,6 +291,13 @@ monotime_init_internal(void)
|
|||||||
void
|
void
|
||||||
monotime_get(monotime_t *out)
|
monotime_get(monotime_t *out)
|
||||||
{
|
{
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
if (monotime_mocking_enabled) {
|
||||||
|
out->abstime_ = (mock_time_nsec * mach_time_info.denom)
|
||||||
|
/ mach_time_info.numer;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
out->abstime_ = mach_absolute_time();
|
out->abstime_ = mach_absolute_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +329,13 @@ monotime_init_internal(void)
|
|||||||
void
|
void
|
||||||
monotime_get(monotime_t *out)
|
monotime_get(monotime_t *out)
|
||||||
{
|
{
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
if (monotime_mocking_enabled) {
|
||||||
|
out->ts_.tv_sec = mock_time_nsec / ONE_BILLION;
|
||||||
|
out->ts_.tv_nsec = mock_time_nsec % ONE_BILLION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
}
|
}
|
||||||
@ -262,6 +344,13 @@ monotime_get(monotime_t *out)
|
|||||||
void
|
void
|
||||||
monotime_coarse_get(monotime_coarse_t *out)
|
monotime_coarse_get(monotime_coarse_t *out)
|
||||||
{
|
{
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
if (monotime_mocking_enabled) {
|
||||||
|
out->ts_.tv_sec = mock_time_nsec_coarse / ONE_BILLION;
|
||||||
|
out->ts_.tv_nsec = mock_time_nsec_coarse % ONE_BILLION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int r = clock_gettime(CLOCK_MONOTONIC_COARSE, &out->ts_);
|
int r = clock_gettime(CLOCK_MONOTONIC_COARSE, &out->ts_);
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
}
|
}
|
||||||
@ -323,6 +412,13 @@ monotime_get(monotime_t *out)
|
|||||||
monotime_init();
|
monotime_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
if (monotime_mocking_enabled) {
|
||||||
|
out->pcount_ = (mock_time_nsec * ticks_per_second) / ONE_BILLION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
||||||
|
|
||||||
https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
|
https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
|
||||||
@ -340,6 +436,13 @@ monotime_get(monotime_t *out)
|
|||||||
void
|
void
|
||||||
monotime_coarse_get(monotime_coarse_t *out)
|
monotime_coarse_get(monotime_coarse_t *out)
|
||||||
{
|
{
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
if (monotime_mocking_enabled) {
|
||||||
|
out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (GetTickCount64_fn) {
|
if (GetTickCount64_fn) {
|
||||||
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
||||||
} else {
|
} else {
|
||||||
@ -424,11 +527,6 @@ monotime_diff_nsec(const monotime_t *start,
|
|||||||
#error "No way to implement monotonic timers."
|
#error "No way to implement monotonic timers."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static monotime_t initialized_at;
|
|
||||||
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
||||||
static monotime_coarse_t initialized_at_coarse;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the monotonic timer subsystem. Must be called before any
|
* Initialize the monotonic timer subsystem. Must be called before any
|
||||||
* monotonic timer functions. This function is idempotent.
|
* monotonic timer functions. This function is idempotent.
|
||||||
|
@ -130,6 +130,15 @@ void tor_gettimeofday(struct timeval *timeval);
|
|||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
void tor_sleep_msec(int msec);
|
void tor_sleep_msec(int msec);
|
||||||
|
|
||||||
|
void monotime_enable_test_mocking(void);
|
||||||
|
void monotime_disable_test_mocking(void);
|
||||||
|
void monotime_set_mock_time_nsec(int64_t);
|
||||||
|
#if defined(MONOTIME_COARSE_FN_IS_DIFFERENT)
|
||||||
|
void monotime_coarse_set_mock_time_nsec(int64_t);
|
||||||
|
#else
|
||||||
|
#define monotime_coarse_set_mock_time_nsec monotime_set_mock_time_nsec
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPAT_TIME_PRIVATE
|
#ifdef COMPAT_TIME_PRIVATE
|
||||||
|
Loading…
Reference in New Issue
Block a user