[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Actually make monotonic time functions mockable.
commit 2d26b1a54901bff8f508bfebeea3fb471cf36a9d
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Thu Jul 21 11:04:22 2016 +0200
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.
---
src/common/compat_time.c | 108 ++++++++++++++++++++++++++++++++++++++++++++---
src/common/compat_time.h | 9 ++++
2 files changed, 112 insertions(+), 5 deletions(-)
diff --git a/src/common/compat_time.c b/src/common/compat_time.c
index b7d69cf..52abfeb 100644
--- a/src/common/compat_time.c
+++ b/src/common/compat_time.c
@@ -118,6 +118,74 @@ tor_gettimeofday(struct timeval *timeval)
/** True iff monotime_init has been called. */
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. */
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
@@ -223,6 +291,13 @@ monotime_init_internal(void)
void
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();
}
@@ -254,6 +329,13 @@ monotime_init_internal(void)
void
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_);
tor_assert(r == 0);
}
@@ -262,6 +344,13 @@ monotime_get(monotime_t *out)
void
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_);
tor_assert(r == 0);
}
@@ -323,6 +412,13 @@ monotime_get(monotime_t *out)
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
https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
@@ -340,6 +436,13 @@ monotime_get(monotime_t *out)
void
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) {
out->tick_count_ = (int64_t)GetTickCount64_fn();
} else {
@@ -424,11 +527,6 @@ monotime_diff_nsec(const monotime_t *start,
#error "No way to implement monotonic timers."
#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
* monotonic timer functions. This function is idempotent.
diff --git a/src/common/compat_time.h b/src/common/compat_time.h
index 8d61bc2..de6994f 100644
--- a/src/common/compat_time.h
+++ b/src/common/compat_time.h
@@ -130,6 +130,15 @@ void tor_gettimeofday(struct timeval *timeval);
#ifdef TOR_UNIT_TESTS
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
#ifdef COMPAT_TIME_PRIVATE
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits