aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2012-02-16 19:15:01 -0800
committerEthan Jackson <ethan@nicira.com>2012-03-02 13:30:32 -0800
commit0a68ffd2347e96447c5b4751c9e5ac65d5100a56 (patch)
tree6fa7d0da1333660e990612fe740cfe128e6d66f3 /tests
parentffc86c0db7d5ad44cd0ec513d08f0160afa06a9c (diff)
python: Port unixctl to Python.
Many of the currently implemented Python daemons, and likely many daemons to be implemented in the future, could benefit from unixctl support even if only to implement "exit" and "version" commands. This patch implements unixctl in Python. Signed-off-by: Ethan Jackson <ethan@nicira.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/appctl.py68
-rw-r--r--tests/atlocal.in2
-rw-r--r--tests/automake.mk3
-rw-r--r--tests/test-unixctl.py85
-rw-r--r--tests/testsuite.at1
-rw-r--r--tests/unixctl-py.at159
6 files changed, 318 insertions, 0 deletions
diff --git a/tests/appctl.py b/tests/appctl.py
new file mode 100644
index 00000000..bc694819
--- /dev/null
+++ b/tests/appctl.py
@@ -0,0 +1,68 @@
+# Copyright (c) 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.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import sys
+
+import ovs.daemon
+import ovs.unixctl
+import ovs.util
+import ovs.vlog
+
+
+def connect_to_target(target):
+ error, str_result = ovs.unixctl.socket_name_from_target(target)
+ if error:
+ ovs.util.ovs_fatal(error, str_result)
+ else:
+ socket_name = str_result
+
+ error, client = ovs.unixctl.UnixctlClient.create(socket_name)
+ if error:
+ ovs.util.ovs_fatal(error, "cannot connect to \"%s\"" % socket_name)
+
+ return client
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Python Implementation of"
+ " ovs-appctl.")
+ parser.add_argument("-t", "--target", default="ovs-vswitchd",
+ help="pidfile or socket to contact")
+
+ parser.add_argument("command", metavar="COMMAND",
+ help="Command to run.")
+ parser.add_argument("argv", metavar="ARG", nargs="*",
+ help="Arguments to the command.")
+ args = parser.parse_args()
+
+ ovs.vlog.Vlog.init()
+ target = args.target
+ client = connect_to_target(target)
+ err_no, error, result = client.transact(args.command, args.argv)
+ client.close()
+
+ if err_no:
+ ovs.util.ovs_fatal(err_no, "%s: transaction error" % target)
+ elif error is not None:
+ sys.stderr.write(error)
+ ovs.util.ovs_error(0, "%s: server returned an error" % target)
+ sys.exit(2)
+ else:
+ assert result is not None
+ sys.stdout.write(result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/atlocal.in b/tests/atlocal.in
index 1d37b59a..400a5c58 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -1,4 +1,6 @@
# -*- shell-script -*-
+VERSION='@VERSION@'
+BUILDNR='@BUILDNR@'
HAVE_OPENSSL='@HAVE_OPENSSL@'
HAVE_PYTHON='@HAVE_PYTHON@'
PERL='@PERL@'
diff --git a/tests/automake.mk b/tests/automake.mk
index a2ed7d76..77281579 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -24,6 +24,7 @@ TESTSUITE_AT = \
tests/vconn.at \
tests/file_name.at \
tests/aes128.at \
+ tests/unixctl-py.at \
tests/uuid.at \
tests/json.at \
tests/jsonrpc.at \
@@ -353,12 +354,14 @@ EXTRA_DIST += tests/choose-port.pl
# Python tests.
CHECK_PYFILES = \
+ tests/appctl.py \
tests/test-daemon.py \
tests/test-json.py \
tests/test-jsonrpc.py \
tests/test-ovsdb.py \
tests/test-reconnect.py \
tests/MockXenAPI.py \
+ tests/test-unixctl.py \
tests/test-vlog.py
EXTRA_DIST += $(CHECK_PYFILES)
PYCOV_CLEAN_FILES += $(CHECK_PYFILES:.py=.py,cover) .coverage
diff --git a/tests/test-unixctl.py b/tests/test-unixctl.py
new file mode 100644
index 00000000..cb9fed22
--- /dev/null
+++ b/tests/test-unixctl.py
@@ -0,0 +1,85 @@
+# Copyright (c) 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.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import sys
+
+import ovs.daemon
+import ovs.unixctl
+
+vlog = ovs.vlog.Vlog("test-unixctl")
+exiting = False
+
+def unixctl_exit(conn, unused_argv, aux):
+ assert aux == "aux_exit"
+ global exiting
+
+ exiting = True
+ conn.reply(None)
+
+
+def unixctl_echo(conn, argv, aux):
+ assert aux == "aux_echo"
+ conn.reply(str(argv))
+
+
+def unixctl_echo_error(conn, argv, aux):
+ assert aux == "aux_echo_error"
+ conn.reply_error(str(argv))
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Open vSwitch unixctl test program for Python")
+ parser.add_argument("--unixctl", help="UNIXCTL socket location or 'none'.")
+
+ ovs.daemon.add_args(parser)
+ ovs.vlog.add_args(parser)
+ args = parser.parse_args()
+ ovs.daemon.handle_args(args)
+ ovs.vlog.handle_args(args)
+
+ ovs.daemon.daemonize_start()
+ error, server = ovs.unixctl.UnixctlServer.create(args.unixctl)
+ if error:
+ ovs.util.ovs_fatal(error, "could not create unixctl server at %s"
+ % args.unixctl, vlog)
+
+ ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, "aux_exit")
+ ovs.unixctl.command_register("echo", "[arg ...]", 1, 2, unixctl_echo,
+ "aux_echo")
+ ovs.unixctl.command_register("echo_error", "[arg ...]", 1, 2,
+ unixctl_echo_error, "aux_echo_error")
+ ovs.daemon.daemonize_complete()
+
+ vlog.info("Entering run loop.")
+ poller = ovs.poller.Poller()
+ while not exiting:
+ server.run()
+ server.wait(poller)
+ if exiting:
+ poller.immediate_wake()
+ poller.block()
+ server.close()
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except SystemExit:
+ # Let system.exit() calls complete normally
+ raise
+ except:
+ vlog.exception("traceback")
+ sys.exit(ovs.daemon.RESTART_EXIT_CODE)
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 7711ba30..c9561e77 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -55,6 +55,7 @@ m4_include([tests/learn.at])
m4_include([tests/vconn.at])
m4_include([tests/file_name.at])
m4_include([tests/aes128.at])
+m4_include([tests/unixctl-py.at])
m4_include([tests/uuid.at])
m4_include([tests/json.at])
m4_include([tests/jsonrpc.at])
diff --git a/tests/unixctl-py.at b/tests/unixctl-py.at
new file mode 100644
index 00000000..1d435baa
--- /dev/null
+++ b/tests/unixctl-py.at
@@ -0,0 +1,159 @@
+AT_BANNER([unixctl])
+
+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], [])
+OVS_WAIT_WHILE([test -s ovs-vswitchd.pid])
+
+AT_CHECK([$PYTHON $srcdir/appctl.py -t ovsdb-server exit], [0], [])
+OVS_WAIT_WHILE([test -s ovsdb-server.pid])
+AT_CLEANUP
+
+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([head -1 stdout], [0], [dnl
+The available commands are:
+])
+mv stdout expout
+AT_CHECK([$PYTHON $srcdir/appctl.py help], [0], [expout])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+
+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([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([ovs-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([ovs-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([ovs-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([ovs-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])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+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_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([tail -1 stderr], [0], [dnl
+appctl.py: cannot connect to "/bogus/path.pid" (No such file or directory)
+])
+
+AT_CLEANUP
+
+AT_SETUP([unixctl server - Python])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+OVS_RUNDIR=$PWD; export OVS_RUNDIR
+OVS_LOGDIR=$PWD; export OVS_LOGDIR
+OVS_SYSCONFDIR=$PWD; export OVS_SYSCONFDIR
+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([cat stdout], [0], [dnl
+The available commands are:
+ echo [[arg ...]]
+ echo_error [[arg ...]]
+ exit
+ help
+ version
+])
+mv stdout expout
+AT_CHECK([$PYTHON $srcdir/appctl.py -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([ovs-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([ovs-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([ovs-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([ovs-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([ovs-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([ovs-appctl -t test-unixctl.py exit])
+trap '' 0]
+AT_CLEANUP
+
+
+AT_SETUP([unixctl server errors - Python])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+AT_CHECK($PYTHON $srcdir/test-unixctl.py --unixctl $PWD/bogus/path, [1], [], [ignore])
+AT_CLEANUP