aboutsummaryrefslogtreecommitdiff
path: root/src/test/test-timers.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-04-13 15:30:59 -0400
committerNick Mathewson <nickm@torproject.org>2016-05-09 14:04:53 -0400
commit118556e4b32c30d91c2d132c5f8d3cb8e551fafc (patch)
treec75535a3e663acade39c703ea84e2dadf0f910bc /src/test/test-timers.c
parentdcf948da0652ca13f5b44f0e15e062f1ff3f8993 (diff)
downloadtor-118556e4b32c30d91c2d132c5f8d3cb8e551fafc.tar.gz
tor-118556e4b32c30d91c2d132c5f8d3cb8e551fafc.zip
Quick-and-dirty test for timers code.
Diffstat (limited to 'src/test/test-timers.c')
-rw-r--r--src/test/test-timers.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/test/test-timers.c b/src/test/test-timers.c
new file mode 100644
index 0000000000..83a5e1ba41
--- /dev/null
+++ b/src/test/test-timers.c
@@ -0,0 +1,101 @@
+/* Copyright 2016, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
+#include "compat.h"
+#include "compat_libevent.h"
+#include "crypto.h"
+#include "timers.h"
+#include "util.h"
+
+#define N_TIMERS 1000
+#define MAX_DURATION 30
+
+static struct timeval fire_at[N_TIMERS] = {{0,0}};
+static int fired[N_TIMERS] = {0};
+static struct timeval difference[N_TIMERS] = {{0,0}};
+static tor_timer_t *timers[N_TIMERS] = {NULL};
+
+static int n_fired = 0;
+
+static void
+timer_cb(tor_timer_t *t, void *arg, const struct timeval *now)
+{
+ tor_timer_t **t_ptr = arg;
+ tor_assert(*t_ptr == t);
+ int idx = (int) (t_ptr - timers);
+ ++fired[idx];
+ timersub(now, &fire_at[idx], &difference[idx]);
+ ++n_fired;
+ // printf("%d / %d\n",n_fired, N_TIMERS);
+ if (n_fired == N_TIMERS) {
+ event_base_loopbreak(tor_libevent_get_base());
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+ tor_libevent_cfg cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ tor_libevent_initialize(&cfg);
+ timers_initialize();
+
+ int i;
+ struct timeval now;
+ tor_gettimeofday(&now);
+ for (i = 0; i < N_TIMERS; ++i) {
+ struct timeval delay;
+ delay.tv_sec = crypto_rand_int_range(0,MAX_DURATION);
+ delay.tv_usec = crypto_rand_int_range(0,1000000);
+ timeradd(&now, &delay, &fire_at[i]);
+ timers[i] = timer_new(timer_cb, &timers[i], 0);
+ timer_schedule(timers[i], &delay);
+ }
+
+ event_base_loop(tor_libevent_get_base(), 0);
+
+ uint64_t total_difference = 0;
+ uint64_t total_square_difference = 0;
+ tor_assert(n_fired == N_TIMERS);
+ for (i = 0; i < N_TIMERS; ++i) {
+ tor_assert(fired[i] == 1);
+ uint64_t diff = difference[i].tv_usec + difference[i].tv_sec * 1000000;
+ total_difference += diff;
+ total_square_difference += diff*diff;
+ }
+ const uint64_t mean_diff = total_difference / N_TIMERS;
+ printf("mean difference: "U64_FORMAT" usec\n",
+ U64_PRINTF_ARG(mean_diff));
+
+ const double mean_sq = ((double)total_square_difference) / N_TIMERS;
+ const double sq_mean = mean_diff * mean_diff;
+ const double stddev = sqrt(mean_sq - sq_mean);
+ printf("standard deviation: %lf usec\n", stddev);
+
+ if (mean_diff > 500*1000 || stddev > 500*1000) {
+ printf("Either your system is under ridiculous load, or the "
+ "timer backend is broken.\n");
+ return 1;
+ } else if (mean_diff > 2000 || stddev > 2000) {
+ printf("Either your system is a bit slow or the "
+ "timer backend is odd.\n");
+ return 0;
+ } else {
+ printf("Looks good enough.\n");
+ }
+ return 0;
+}