From f4ec6ff479ace8f9b893f883557235f2ea6bab8f Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Tue, 6 Mar 2012 16:10:46 -0800 Subject: [PATCH] unixctl: Timeout unit tests instead of hanging. We've seen some unixctl tests hang indefinitely which makes them difficult to debug. ovs-appctl and appctl.py calls to timeout instead. Signed-off-by: Ethan Jackson --- tests/appctl.py | 6 ++++ tests/test-unixctl.py | 5 ++++ tests/unixctl-py.at | 66 ++++++++++++++++++++++-------------------- utilities/ovs-appctl.c | 6 ++++ 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/tests/appctl.py b/tests/appctl.py index bc694819..4a2865e1 100644 --- a/tests/appctl.py +++ b/tests/appctl.py @@ -13,6 +13,7 @@ # limitations under the License. import argparse +import signal import sys import ovs.daemon @@ -45,8 +46,13 @@ def main(): help="Command to run.") parser.add_argument("argv", metavar="ARG", nargs="*", help="Arguments to the command.") + parser.add_argument("-T", "--timeout", metavar="SECS", + help="wait at most SECS seconds for a response") args = parser.parse_args() + if args.timeout: + signal.alarm(int(args.timeout)) + ovs.vlog.Vlog.init() target = args.target client = connect_to_target(target) diff --git a/tests/test-unixctl.py b/tests/test-unixctl.py index cb9fed22..c262a958 100644 --- a/tests/test-unixctl.py +++ b/tests/test-unixctl.py @@ -39,6 +39,10 @@ def unixctl_echo_error(conn, argv, aux): conn.reply_error(str(argv)) +def unixctl_block(conn, unused_argv, unused_aux): + pass + + def main(): parser = argparse.ArgumentParser( description="Open vSwitch unixctl test program for Python") @@ -61,6 +65,7 @@ def main(): "aux_echo") ovs.unixctl.command_register("echo_error", "[arg ...]", 1, 2, unixctl_echo_error, "aux_echo_error") + ovs.unixctl.command_register("block", "", 0, 0, unixctl_block, None) ovs.daemon.daemonize_complete() vlog.info("Entering run loop.") diff --git a/tests/unixctl-py.at b/tests/unixctl-py.at index 1d435baa..8317add8 100644 --- a/tests/unixctl-py.at +++ b/tests/unixctl-py.at @@ -1,13 +1,16 @@ AT_BANNER([unixctl]) +m4_define([APPCTL], [ovs-appctl --timeout 20]) +m4_define([PYAPPCTL], [$PYTHON $srcdir/appctl.py --timeout 20]) + AT_SETUP([unixctl ovs-vswitchd exit - Python]) AT_SKIP_IF([test $HAVE_PYTHON = no]) OVS_VSWITCHD_START -AT_CHECK([$PYTHON $srcdir/appctl.py -t ovs-vswitchd exit], [0], []) +AT_CHECK([PYAPPCTL -t ovs-vswitchd exit], [0], []) OVS_WAIT_WHILE([test -s ovs-vswitchd.pid]) -AT_CHECK([$PYTHON $srcdir/appctl.py -t ovsdb-server exit], [0], []) +AT_CHECK([PYAPPCTL -t ovsdb-server exit], [0], []) OVS_WAIT_WHILE([test -s ovsdb-server.pid]) AT_CLEANUP @@ -15,12 +18,12 @@ AT_SETUP([unixctl ovs-vswitchd help - Python]) AT_SKIP_IF([test $HAVE_PYTHON = no]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl help], [0], [stdout]) +AT_CHECK([APPCTL help], [0], [stdout]) AT_CHECK([head -1 stdout], [0], [dnl The available commands are: ]) mv stdout expout -AT_CHECK([$PYTHON $srcdir/appctl.py help], [0], [expout]) +AT_CHECK([PYAPPCTL help], [0], [expout]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -30,40 +33,40 @@ AT_SETUP([unixctl ovs-vswitchd arguments - Python]) AT_SKIP_IF([test $HAVE_PYTHON = no]) OVS_VSWITCHD_START -AT_CHECK([ovs-appctl bond/hash], [2], [], [stderr]) +AT_CHECK([APPCTL bond/hash], [2], [], [stderr]) AT_CHECK([head -1 stderr], [0], [dnl "bond/hash" command requires at least 1 arguments ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py bond/hash], [2], [], [experr]) +AT_CHECK([PYAPPCTL bond/hash], [2], [], [experr]) -AT_CHECK([ovs-appctl bond/hash mac], [2], [], [stderr]) +AT_CHECK([APPCTL bond/hash mac], [2], [], [stderr]) AT_CHECK([head -1 stderr], [0], [dnl invalid mac ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py bond/hash mac], [2], [], [experr]) +AT_CHECK([PYAPPCTL bond/hash mac], [2], [], [experr]) -AT_CHECK([ovs-appctl bond/hash mac vlan], [2], [], [stderr]) +AT_CHECK([APPCTL bond/hash mac vlan], [2], [], [stderr]) AT_CHECK([head -1 stderr], [0], [dnl invalid vlan ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py bond/hash mac vlan], [2], [], [experr]) +AT_CHECK([PYAPPCTL bond/hash mac vlan], [2], [], [experr]) -AT_CHECK([ovs-appctl bond/hash mac vlan basis], [2], [], [stderr]) +AT_CHECK([APPCTL bond/hash mac vlan basis], [2], [], [stderr]) AT_CHECK([head -1 stderr], [0], [dnl invalid vlan ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py bond/hash vlan basis], [2], [], [experr]) +AT_CHECK([PYAPPCTL bond/hash vlan basis], [2], [], [experr]) -AT_CHECK([ovs-appctl bond/hash mac vlan basis extra], [2], [], [stderr]) +AT_CHECK([APPCTL bond/hash mac vlan basis extra], [2], [], [stderr]) AT_CHECK([head -1 stderr], [0], [dnl "bond/hash" command takes at most 3 arguments ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py bond/hash mac vlan basis extra], [2], [], [experr]) +AT_CHECK([PYAPPCTL bond/hash mac vlan basis extra], [2], [], [experr]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -72,12 +75,12 @@ AT_SETUP([unixctl bad target - Python]) OVS_RUNDIR=$PWD; export OVS_RUNDIR AT_SKIP_IF([test $HAVE_PYTHON = no]) -AT_CHECK([$PYTHON $srcdir/appctl.py -t bogus doit], [1], [], [stderr]) +AT_CHECK([PYAPPCTL -t bogus doit], [1], [], [stderr]) AT_CHECK_UNQUOTED([tail -1 stderr], [0], [dnl appctl.py: cannot read pidfile "$PWD/bogus.pid" (No such file or directory) ]) -AT_CHECK([$PYTHON $srcdir/appctl.py -t /bogus/path.pid doit], [1], [], [stderr]) +AT_CHECK([PYAPPCTL -t /bogus/path.pid doit], [1], [], [stderr]) AT_CHECK([tail -1 stderr], [0], [dnl appctl.py: cannot connect to "/bogus/path.pid" (No such file or directory) ]) @@ -93,9 +96,10 @@ trap 'kill `cat test-unixctl.py.pid`' 0 AT_CAPTURE_FILE([$PWD/test-unixctl.py.log]) AT_CHECK([$PYTHON $srcdir/test-unixctl.py --log-file --pidfile --detach]) -AT_CHECK([ovs-appctl -t test-unixctl.py help], [0], [stdout]) +AT_CHECK([APPCTL -t test-unixctl.py help], [0], [stdout]) AT_CHECK([cat stdout], [0], [dnl The available commands are: + block echo [[arg ...]] echo_error [[arg ...]] exit @@ -103,52 +107,52 @@ The available commands are: version ]) mv stdout expout -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py help], [0], [expout]) +AT_CHECK([PYAPPCTL -t test-unixctl.py help], [0], [expout]) AT_CHECK([echo "test-unixctl.py (Open vSwitch) $VERSION $BUILDNR" > expout]) -AT_CHECK([ovs-appctl -t test-unixctl.py version], [0], [expout]) -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py version], [0], [expout]) +AT_CHECK([APPCTL -t test-unixctl.py version], [0], [expout]) +AT_CHECK([PYAPPCTL -t test-unixctl.py version], [0], [expout]) -AT_CHECK([ovs-appctl -t test-unixctl.py echo robot ninja], [0], [stdout]) +AT_CHECK([APPCTL -t test-unixctl.py echo robot ninja], [0], [stdout]) AT_CHECK([cat stdout], [0], [dnl [[u'robot', u'ninja']] ]) mv stdout expout -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py echo robot ninja], [0], [expout]) +AT_CHECK([PYAPPCTL -t test-unixctl.py echo robot ninja], [0], [expout]) -AT_CHECK([ovs-appctl -t test-unixctl.py echo_error robot ninja], [2], [], [stderr]) +AT_CHECK([APPCTL -t test-unixctl.py echo_error robot ninja], [2], [], [stderr]) AT_CHECK([cat stderr], [0], [dnl [[u'robot', u'ninja']] ovs-appctl: test-unixctl.py: server returned an error ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py echo_error robot ninja], [2], [], [experr]) +AT_CHECK([PYAPPCTL -t test-unixctl.py echo_error robot ninja], [2], [], [experr]) -AT_CHECK([ovs-appctl -t test-unixctl.py echo], [2], [], [stderr]) +AT_CHECK([APPCTL -t test-unixctl.py echo], [2], [], [stderr]) AT_CHECK([cat stderr], [0], [dnl "echo" command requires at least 1 arguments ovs-appctl: test-unixctl.py: server returned an error ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py echo], [2], [], [experr]) +AT_CHECK([PYAPPCTL -t test-unixctl.py echo], [2], [], [experr]) -AT_CHECK([ovs-appctl -t test-unixctl.py echo robot ninja pirates], [2], [], [stderr]) +AT_CHECK([APPCTL -t test-unixctl.py echo robot ninja pirates], [2], [], [stderr]) AT_CHECK([cat stderr], [0], [dnl "echo" command takes at most 2 arguments ovs-appctl: test-unixctl.py: server returned an error ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py echo robot ninja pirates], [2], [], [experr]) +AT_CHECK([PYAPPCTL -t test-unixctl.py echo robot ninja pirates], [2], [], [experr]) -AT_CHECK([ovs-appctl -t test-unixctl.py bogus], [2], [], [stderr]) +AT_CHECK([APPCTL -t test-unixctl.py bogus], [2], [], [stderr]) AT_CHECK([cat stderr], [0], [dnl "bogus" is not a valid command ovs-appctl: test-unixctl.py: server returned an error ]) sed 's/ovs-appctl/appctl.py/' stderr > experr -AT_CHECK([$PYTHON $srcdir/appctl.py -t test-unixctl.py bogus], [2], [], [experr]) +AT_CHECK([PYAPPCTL -t test-unixctl.py bogus], [2], [], [experr]) -AT_CHECK([ovs-appctl -t test-unixctl.py exit]) +AT_CHECK([APPCTL -t test-unixctl.py exit]) trap '' 0] AT_CLEANUP diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c index 241b6c04..f761d5ac 100644 --- a/utilities/ovs-appctl.c +++ b/utilities/ovs-appctl.c @@ -97,6 +97,7 @@ Common commands:\n\ 'off', 'emer', 'err', 'warn', 'info', or 'dbg' ('dbg', bydefault)\n\ vlog/reopen Make the program reopen its log file\n\ Other options:\n\ + --timeout=SECS wait at most SECS seconds for a response\n\ -h, --help Print this helpful information\n\ -V, --version Display ovs-appctl version information\n", program_name, program_name); @@ -111,6 +112,7 @@ parse_command_line(int argc, char *argv[]) {"execute", no_argument, NULL, 'e'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, + {"timeout", required_argument, NULL, 'T'}, {NULL, 0, NULL, 0}, }; const char *target; @@ -147,6 +149,10 @@ parse_command_line(int argc, char *argv[]) usage(); break; + case 'T': + time_alarm(atoi(optarg)); + break; + case 'V': ovs_print_version(0, 0); exit(EXIT_SUCCESS); -- 2.30.2