aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-02-28 14:57:13 -0800
committerBen Pfaff <blp@nicira.com>2012-03-02 11:06:58 -0800
commitc521d98befd333f25913b06eebc4947575cc5915 (patch)
treec58fdb97c5fbc2b997ba6cbefa9b2a6a9422afe5
parente519d31e1e5b4aa1417d71b15836de9a012feb02 (diff)
timeval: Add "time/stop" unixctl command, for use in unit tests.
Although we try to avoid it, some unit tests are necessarily timing-sensitive. The new "time/stop" command that this commit adds should help with that, by preventing time from advancing from the viewpoint of the OVS "timeval" functions except when "time/warp" explicitly advances the current time. This should allow the unit tests that need it to become reproducible regardless of the speed at which the tests run. This commit adds one use of "time/stop" to the unit test suite, in the one timing-sensitive test of which I am currently aware. Bug #9782. Reported-by: Tim Chen <tchen@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--lib/timeval.c43
-rw-r--r--tests/ofproto-dpif.at1
2 files changed, 33 insertions, 11 deletions
diff --git a/lib/timeval.c b/lib/timeval.c
index c8c02bdc..ad01ee3e 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,8 +51,9 @@ static volatile sig_atomic_t monotonic_tick = true;
static struct timespec wall_time;
static struct timespec monotonic_time;
-/* Fixed monotonic time offset, for use by unit tests. */
-static struct timespec warp_offset;
+/* features for use by unit tests. */
+static struct timespec warp_offset; /* Offset added to monotonic_time. */
+static bool time_stopped; /* Disables real-time updates, if true. */
/* Time at which to die with SIGALRM (if not TIME_MIN). */
static time_t deadline = TIME_MIN;
@@ -182,15 +183,17 @@ refresh_monotonic(void)
{
time_init();
- if (monotonic_clock == CLOCK_MONOTONIC) {
- clock_gettime(monotonic_clock, &monotonic_time);
- } else {
- refresh_wall_if_ticked();
- monotonic_time = wall_time;
- }
- timespec_add(&monotonic_time, &monotonic_time, &warp_offset);
+ if (!time_stopped) {
+ if (monotonic_clock == CLOCK_MONOTONIC) {
+ clock_gettime(monotonic_clock, &monotonic_time);
+ } else {
+ refresh_wall_if_ticked();
+ monotonic_time = wall_time;
+ }
+ timespec_add(&monotonic_time, &monotonic_time, &warp_offset);
- monotonic_tick = false;
+ monotonic_tick = false;
+ }
}
/* Forces a refresh of the current time from the kernel. It is not usually
@@ -551,6 +554,22 @@ get_cpu_usage(void)
/* Unixctl interface. */
+/* "time/stop" stops the monotonic time returned by e.g. time_msec() from
+ * advancing, except due to later calls to "time/warp". */
+static void
+timeval_stop_cb(struct unixctl_conn *conn,
+ int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
+ void *aux OVS_UNUSED)
+{
+ time_stopped = true;
+ unixctl_command_reply(conn, 200, NULL);
+}
+
+/* "time/warp MSECS" advances the current monotonic time by the specified
+ * number of milliseconds. Unless "time/stop" has also been executed, the
+ * monotonic clock continues to tick forward at the normal rate afterward.
+ *
+ * Does not affect wall clock readings. */
static void
timeval_warp_cb(struct unixctl_conn *conn,
int argc OVS_UNUSED, const char *argv[], void *aux OVS_UNUSED)
@@ -567,12 +586,14 @@ timeval_warp_cb(struct unixctl_conn *conn,
ts.tv_sec = msecs / 1000;
ts.tv_nsec = (msecs % 1000) * 1000 * 1000;
timespec_add(&warp_offset, &warp_offset, &ts);
+ timespec_add(&monotonic_time, &monotonic_time, &ts);
unixctl_command_reply(conn, 200, "warped");
}
void
timeval_dummy_register(void)
{
+ unixctl_command_register("time/stop", "", 0, 0, timeval_stop_cb, NULL);
unixctl_command_register("time/warp", "MSECS", 1, 1,
timeval_warp_cb, NULL);
}
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 87818fb8..4b2299c9 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -951,6 +951,7 @@ OVS_VSWITCHD_START(
AT_CHECK([test-netflow --detach --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
+AT_CHECK([ovs-appctl time/stop])
n=1
while test $n -le 60; do
n=`expr $n + 1`