summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-05-09 14:06:10 -0400
committerNick Mathewson <nickm@torproject.org>2016-05-09 14:06:10 -0400
commit69380033d644d39a7369e0cd2b2cb7fd5cd7c695 (patch)
tree4c06dd268817276028ece95eeb6d1db91a7cb9a6 /src/test
parent641cdc345c7a0e8123cee9a7b3864b63ba389afa (diff)
parentaf132fc299f837f8749278099e6257cea3795e8e (diff)
downloadtor-69380033d644d39a7369e0cd2b2cb7fd5cd7c695.tar.gz
tor-69380033d644d39a7369e0cd2b2cb7fd5cd7c695.zip
Merge branch 'timeouts_v2_squashed'
Diffstat (limited to 'src/test')
-rw-r--r--src/test/include.am16
-rw-r--r--src/test/test-timers.c133
2 files changed, 148 insertions, 1 deletions
diff --git a/src/test/include.am b/src/test/include.am
index a3543ddbf4..991b24963a 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -17,6 +17,7 @@ endif
TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
src/test/test_workqueue src/test/test_keygen.sh \
+ src/test/test-timers \
$(TESTSCRIPTS)
# These flavors are run using automake's test-driver and test-network.sh
@@ -40,7 +41,8 @@ noinst_PROGRAMS+= \
src/test/test-memwipe \
src/test/test-child \
src/test/test_workqueue \
- src/test/test-switch-id
+ src/test/test-switch-id \
+ src/test/test-timers
endif
src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
@@ -128,6 +130,8 @@ src_test_test_slow_SOURCES = \
src_test_test_memwipe_SOURCES = \
src/test/test-memwipe.c
+src_test_test_timers_SOURCES = \
+ src/test/test-timers.c
src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
@@ -191,6 +195,16 @@ src_test_test_workqueue_LDADD = src/or/libtor-testing.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+src_test_test_timers_CPPFLAGS = $(src_test_test_CPPFLAGS)
+src_test_test_timers_CFLAGS = $(src_test_test_CFLAGS)
+src_test_test_timers_LDADD = \
+ src/common/libor-event-testing.a \
+ src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \
+ src/common/libor-testing.a \
+ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
+ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+src_test_test_timers_LDFLAGS = $(src_test_test_LDFLAGS)
+
noinst_HEADERS+= \
src/test/fakechans.h \
src/test/log_test_helpers.h \
diff --git a/src/test/test-timers.c b/src/test/test-timers.c
new file mode 100644
index 0000000000..8f5ba7b78a
--- /dev/null
+++ b/src/test/test-timers.c
@@ -0,0 +1,133 @@
+/* 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
+#define N_DISABLE 5
+
+static struct timeval fire_at[N_TIMERS] = {{0,0}};
+static int is_disabled[N_TIMERS] = {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_active_timers = 0;
+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_active_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;
+ int ret;
+ 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]);
+ timer_schedule(timers[i], &delay);
+ ++n_active_timers;
+ }
+
+ /* Disable some; we'll make sure they don't trigger. */
+ for (i = 0; i < N_DISABLE; ++i) {
+ int idx = crypto_rand_int_range(0, N_TIMERS);
+ if (is_disabled[idx])
+ continue;
+ is_disabled[idx] = 1;
+ timer_disable(timers[idx]);
+ --n_active_timers;
+ }
+
+ event_base_loop(tor_libevent_get_base(), 0);
+
+ int64_t total_difference = 0;
+ uint64_t total_square_difference = 0;
+ tor_assert(n_fired == n_active_timers);
+ for (i = 0; i < N_TIMERS; ++i) {
+ if (is_disabled[i]) {
+ tor_assert(fired[i] == 0);
+ continue;
+ }
+ tor_assert(fired[i] == 1);
+ int64_t diff = difference[i].tv_usec + difference[i].tv_sec * 1000000;
+ total_difference += diff;
+ total_square_difference += diff*diff;
+ }
+ const int64_t mean_diff = total_difference / n_active_timers;
+ printf("mean difference: "U64_FORMAT" usec\n",
+ U64_PRINTF_ARG(mean_diff));
+
+ const double mean_sq = ((double)total_square_difference)/ n_active_timers;
+ const double sq_mean = mean_diff * mean_diff;
+ const double stddev = sqrt(mean_sq - sq_mean);
+ printf("standard deviation: %lf usec\n", stddev);
+
+#define MAX_DIFF_USEC (500*1000)
+#define MAX_STDDEV_USEC (500*1000)
+#define ODD_DIFF_USEC (2000)
+#define ODD_STDDEV_USEC (2000)
+
+ if (mean_diff < 0 || mean_diff > MAX_DIFF_USEC || stddev > MAX_STDDEV_USEC) {
+ printf("Either your system is under ridiculous load, or the "
+ "timer backend is broken.\n");
+ ret = 1;
+ } else if (mean_diff > ODD_DIFF_USEC || stddev > ODD_STDDEV_USEC) {
+ printf("Either your system is a bit slow or the "
+ "timer backend is odd.\n");
+ ret = 0;
+ } else {
+ printf("Looks good enough.\n");
+ ret = 0;
+ }
+
+ timer_free(NULL);
+
+ for (i = 0; i < N_TIMERS; ++i) {
+ timer_free(timers[i]);
+ }
+ timers_shutdown();
+ return ret;
+}