There are no stopwatch users in OVS, so we don't have a good way to
test the unixctl commands, but they are important to cover, as they
are frequently used for debugging OVN.

Adding a new test that creates a bunch of stopwatches and checks
that the 'show' command works as expected with all the options and
'reset' clears all the samples.

This kind of test doesn't belong in library.at, so creating a new
file.  And moving the existing library test into it, so all the
stopwatch tests are in the same place.

Signed-off-by: Ilya Maximets <[email protected]>
---
 tests/automake.mk      |   1 +
 tests/library.at       |   5 --
 tests/stopwatch.at     | 118 +++++++++++++++++++++++++++++++
 tests/test-stopwatch.c | 153 ++++++++++++++++++++++++++++++++++++++++-
 tests/testsuite.at     |   1 +
 5 files changed, 272 insertions(+), 6 deletions(-)
 create mode 100644 tests/stopwatch.at

diff --git a/tests/automake.mk b/tests/automake.mk
index da569b022..a9d972a86 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -36,6 +36,7 @@ TESTSUITE_AT = \
        tests/completion.at \
        tests/checkpatch.at \
        tests/library.at \
+       tests/stopwatch.at \
        tests/heap.at \
        tests/bundle.at \
        tests/classifier.at \
diff --git a/tests/library.at b/tests/library.at
index 82ac80a27..106c0abe7 100644
--- a/tests/library.at
+++ b/tests/library.at
@@ -275,11 +275,6 @@ AT_SETUP([rcu])
 AT_CHECK([ovstest test-rcu], [0], [])
 AT_CLEANUP
 
-AT_SETUP([stopwatch module])
-AT_CHECK([ovstest test-stopwatch], [0], [......
-], [ignore])
-AT_CLEANUP
-
 AT_SETUP([netlink policy])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 AT_SKIP_IF([test "$IS_BSD" = "yes"])
diff --git a/tests/stopwatch.at b/tests/stopwatch.at
new file mode 100644
index 000000000..c651037fa
--- /dev/null
+++ b/tests/stopwatch.at
@@ -0,0 +1,118 @@
+AT_BANNER([stopwatch library])
+
+AT_SETUP([stopwatch module])
+AT_CHECK([ovstest test-stopwatch], [0], [......
+], [ignore])
+AT_CLEANUP
+
+AT_SETUP([stopwatch unixctl])
+
+AT_CHECK([ovstest test-stopwatch-unixctl -voff -vfile:info \
+            --no-chdir --detach --pidfile=stopwatch.pid \
+            --log-file=stopwatch.log --unixctl=stopwatch.ctl],
+         [0], [ignore], [ignore])
+on_exit 'test -e stopwatch.pid && kill $(cat stopwatch.pid)'
+OVS_WAIT_UNTIL([test -e stopwatch.ctl])
+
+m4_define([STOPWATCH_SHOW], [
+  AT_CHECK([ovs-appctl -t $(pwd)/stopwatch.ctl stopwatch/show $1 \
+               m4_if([$2], [], [| grep -v '^ ' | sort], [])], [0], [$3])
+])
+
+STOPWATCH_SHOW([], [], [dnl
+3 stopwatches with no samples
+Statistics for '1 msec'
+Statistics for '1 nsec'
+Statistics for '1 usec'
+Statistics for '100 msec'
+Statistics for '100 nsec'
+Statistics for '100 usec'
+Statistics for '1000 msec'
+Statistics for '1000 nsec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW(["100 usec"], [full], [dnl
+Statistics for '100 usec'
+  Total samples: 1
+  Maximum: 100 usec
+  Minimum: 100 usec
+  95th percentile: 0.000000 usec
+  Short term average: 100.000000 usec
+  Long term average: 100.000000 usec
+])
+
+STOPWATCH_SHOW(["1 nsec"], [full], [dnl
+Statistics for '1 nsec'
+  Total samples: 1
+  Maximum: 1 nsec
+  Minimum: 1 nsec
+  95th percentile: 0.000000 nsec
+  Short term average: 1.000000 nsec
+  Long term average: 1.000000 nsec
+])
+
+STOPWATCH_SHOW([--threshold 10], [], [dnl
+Statistics for '100 msec'
+Statistics for '100 nsec'
+Statistics for '100 usec'
+Statistics for '1000 msec'
+Statistics for '1000 nsec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW([-t 1 msec], [], [dnl
+Statistics for '1 msec'
+Statistics for '100 msec'
+Statistics for '1000 msec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW([-t 100 usec], [], [dnl
+Statistics for '1 msec'
+Statistics for '100 msec'
+Statistics for '100 usec'
+Statistics for '1000 msec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW([-t 100000 nsec], [], [dnl
+Statistics for '1 msec'
+Statistics for '100 msec'
+Statistics for '100 usec'
+Statistics for '1000 msec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW([-t 100 msec], [], [dnl
+Statistics for '100 msec'
+Statistics for '1000 msec'
+])
+
+STOPWATCH_SHOW([-t 101 msec], [], [dnl
+Statistics for '1000 msec'
+])
+
+STOPWATCH_SHOW([-t 101 usec], [], [dnl
+Statistics for '1 msec'
+Statistics for '100 msec'
+Statistics for '1000 msec'
+Statistics for '1000 usec'
+])
+
+STOPWATCH_SHOW([-t 999 usec], [], [dnl
+Statistics for '1 msec'
+Statistics for '100 msec'
+Statistics for '1000 msec'
+Statistics for '1000 usec'
+])
+
+AT_CHECK([ovs-appctl -t $(pwd)/stopwatch.ctl stopwatch/reset])
+
+STOPWATCH_SHOW([], [], [dnl
+12 stopwatches with no samples
+])
+
+AT_CHECK([ovs-appctl -t $(pwd)/stopwatch.ctl exit])
+
+AT_CLEANUP
diff --git a/tests/test-stopwatch.c b/tests/test-stopwatch.c
index 1270cd936..44852db19 100644
--- a/tests/test-stopwatch.c
+++ b/tests/test-stopwatch.c
@@ -16,11 +16,19 @@
 
 #include <config.h>
 #undef NDEBUG
-#include "stopwatch.h"
 #include <assert.h>
+#include <getopt.h>
 #include <math.h>
 #include <stdio.h>
+#include "command-line.h"
+#include "daemon.h"
+#include "fatal-signal.h"
+#include "openvswitch/vlog.h"
+#include "openvswitch/poll-loop.h"
+#include "ovstest.h"
 #include "ovstest.h"
+#include "stopwatch.h"
+#include "unixctl.h"
 #include "util.h"
 
 #define MAX_SAMPLES 100
@@ -192,4 +200,147 @@ test_stopwatch_main(int argc OVS_UNUSED, char *argv[] 
OVS_UNUSED)
     printf("\n");
 }
 
+static void
+stopwatch_unixctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                       const char *argv[] OVS_UNUSED, void *exiting_)
+{
+    bool *exiting = exiting_;
+    *exiting = true;
+    unixctl_command_reply(conn, NULL);
+}
+
+OVS_NO_RETURN static void
+usage(void)
+{
+    printf("%s: Open vSwitch stopwatch test program\n"
+           "usage: %s [OPTIONS]\n",
+           program_name, program_name);
+    daemon_usage();
+    vlog_usage();
+    printf("\nOther options:\n"
+           "  --unixctl=SOCKET        override default control socket name\n"
+           "  -h, --help              display this help message\n"
+           "  -V, --version           display version information\n");
+    exit(EXIT_SUCCESS);
+}
+
+static void
+parse_options(int *argcp, char **argvp[], char **unixctl_pathp)
+{
+    enum {
+        OPT_UNIXCTL = UCHAR_MAX + 1,
+        VLOG_OPTION_ENUMS,
+        DAEMON_OPTION_ENUMS
+    };
+    static const struct option long_options[] = {
+        {"unixctl",     required_argument, NULL, OPT_UNIXCTL},
+        {"help",        no_argument, NULL, 'h'},
+        {"version",     no_argument, NULL, 'V'},
+        DAEMON_LONG_OPTIONS,
+        VLOG_LONG_OPTIONS,
+        {NULL, 0, NULL, 0},
+    };
+    char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
+    int argc = *argcp;
+    char **argv = *argvp;
+
+    for (;;) {
+        int c;
+
+        c = getopt_long(argc, argv, short_options, long_options, NULL);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        case OPT_UNIXCTL:
+            *unixctl_pathp = optarg;
+            break;
+
+        case 'h':
+            usage();
+
+        case 'V':
+            ovs_print_version(0, 0);
+            exit(EXIT_SUCCESS);
+
+        VLOG_OPTION_HANDLERS
+        DAEMON_OPTION_HANDLERS
+
+        case '?':
+            exit(EXIT_FAILURE);
+
+        default:
+            OVS_NOT_REACHED();
+        }
+    }
+    free(short_options);
+
+    *argcp -= optind;
+    *argvp += optind;
+}
+
+static int
+test_stopwatch_unixctl_main(int argc, char *argv[])
+{
+    struct unixctl_server *unixctl;
+    char *unixctl_path = NULL;
+    bool exiting = false;
+
+    ovs_cmdl_proctitle_init(argc, argv);
+    set_program_name(argv[0]);
+    service_start(&argc, &argv);
+    fatal_ignore_sigpipe();
+    parse_options(&argc, &argv, &unixctl_path);
+
+    daemonize_start(false, false);
+    int retval = unixctl_server_create(unixctl_path, &unixctl);
+    if (retval) {
+        exit(EXIT_FAILURE);
+    }
+    unixctl_command_register("exit", "", 0, 0,
+                             stopwatch_unixctl_exit, &exiting);
+    daemonize_complete();
+
+    struct {
+        const char *name;
+        enum stopwatch_units units;
+        int value;
+    } stopwatches[] = {
+        { "1 msec",    SW_MS, 1 },
+        { "1 usec",    SW_US, 1 },
+        { "1 nsec",    SW_NS, 1 },
+        { "100 msec",  SW_MS, 100 },
+        { "100 usec",  SW_US, 100 },
+        { "100 nsec",  SW_NS, 100 },
+        { "1000 msec", SW_MS, 1000 },
+        { "1000 usec", SW_US, 1000 },
+        { "1000 nsec", SW_NS, 1000 },
+    };
+    for (size_t i = 0; i < ARRAY_SIZE(stopwatches); i++) {
+        stopwatch_create(stopwatches[i].name, stopwatches[i].units);
+        stopwatch_start(stopwatches[i].name, 0);
+        stopwatch_stop(stopwatches[i].name, stopwatches[i].value);
+    }
+    stopwatch_create("No samples msec", SW_MS);
+    stopwatch_create("No samples usec", SW_US);
+    stopwatch_create("No samples nsec", SW_NS);
+
+    stopwatch_sync();
+
+    while (!exiting) {
+        unixctl_server_run(unixctl);
+        unixctl_server_wait(unixctl);
+        if (exiting) {
+            poll_immediate_wake();
+        }
+        poll_block();
+    }
+    unixctl_server_destroy(unixctl);
+
+    service_stop();
+    return 0;
+}
+
 OVSTEST_REGISTER("test-stopwatch", test_stopwatch_main);
+OVSTEST_REGISTER("test-stopwatch-unixctl", test_stopwatch_unixctl_main);
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 9d77a9f51..e5bdd7325 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -26,6 +26,7 @@ m4_include([tests/bfd.at])
 m4_include([tests/cfm.at])
 m4_include([tests/lacp.at])
 m4_include([tests/library.at])
+m4_include([tests/stopwatch.at])
 m4_include([tests/heap.at])
 m4_include([tests/bundle.at])
 m4_include([tests/classifier.at])
-- 
2.53.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to