From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:58803) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNhBT-0005Y4-TA for qemu-devel@nongnu.org; Tue, 08 Nov 2011 03:37:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RNhBS-0004aH-Dp for qemu-devel@nongnu.org; Tue, 08 Nov 2011 03:37:31 -0500 Received: from e23smtp05.au.ibm.com ([202.81.31.147]:47473) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNhBR-0004Zn-Gq for qemu-devel@nongnu.org; Tue, 08 Nov 2011 03:37:30 -0500 Received: from /spool/local by e23smtp05.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 8 Nov 2011 08:35:15 +1000 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pA88Y0fa1122380 for ; Tue, 8 Nov 2011 19:34:00 +1100 Received: from d23av02.au.ibm.com (loopback [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pA88avwT016826 for ; Tue, 8 Nov 2011 19:36:57 +1100 Message-ID: <4EB8EA27.9080902@linux.vnet.ibm.com> Date: Tue, 08 Nov 2011 16:36:55 +0800 From: Mark Wu MIME-Version: 1.0 References: <1320678675-21379-1-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1320678675-21379-1-git-send-email-aliguori@us.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: qemu-devel@nongnu.org, Luiz Capitulino When I run this tool, I got two python exceptions. It turned out that both of them were caused by wrong usage. Do you think we need add validation for input to handle these cases? Thanks. 1. Not using '=' for path: $ ./QMP/qmp --path monitor-address Traceback (most recent call last): File "./QMP/qmp", line 120, in sys.exit(main(sys.argv[1:])) File "./QMP/qmp", line 71, in main srv.connect() File "/home/mark/work/source/qemu/QMP/qmp.py", line 85, in connect self.__sock.connect(self.__address) File "", line 1, in connect TypeError: argument must be string or read-only character buffer, not bool Proposed patch: @@ -48,7 +48,8 @@ def main(args): arg, value = arg.split('=', 1) if arg in ['path']: - path = value + if isinstance(value, basestring): + path = value 2. No qmp comand given in command line $ ./QMP/qmp --path=monitor-address Traceback (most recent call last): File "./QMP/qmp", line 120, in sys.exit(main(sys.argv[1:])) File "./QMP/qmp", line 65, in main command, args = args[0], args[1:] IndexError: list index out of range @@ -62,11 +63,17 @@ def main(args): print "QMP path isn't set, use --path or set QMP_PATH" return 1 Proposed patch: - command, args = args[0], args[1:] + if len(args): + command, args = args[0], args[1:] + else: + print 'No command found' + print 'Usage: "qmp [--path=monitor-address] qmp-cmd arguments"' + return 1 On 11/07/2011 11:11 PM, Anthony Liguori wrote: > I wrote this quickly to aid in testing. It's similar to qmp-shell with a few > important differences: > > 1) It is not interactive. That makes it useful for scripting. > > 2) qmp-shell: > > (QEMU) set_password protocol=vnc password=foo > > 3) qmp: > > $ qmp set_password --protocol=vnc --password=foo > > 4) Extensible, git-style interface. If an invalid command name is passed, it > will try to exec qmp-$1. > > 5) It attempts to pretty print the JSON responses in a shell friendly format > such that tools can work with the output. > > Hope others will also find it useful. > > Signed-off-by: Anthony Liguori > --- > QMP/qmp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 120 insertions(+), 0 deletions(-) > create mode 100755 QMP/qmp > > diff --git a/QMP/qmp b/QMP/qmp > new file mode 100755 > index 0000000..7b2a3c7 > --- /dev/null > +++ b/QMP/qmp > @@ -0,0 +1,120 @@ > +#!/usr/bin/python > +# > +# QMP command line tool > +# > +# Copyright IBM, Corp. 2011 > +# > +# Authors: > +# Anthony Liguori > +# > +# This work is licensed under the terms of the GNU GPLv2 or later. > +# See the COPYING file in the top-level directory. > + > +import sys, os > +from qmp import QEMUMonitorProtocol > + > +def print_response(rsp, prefix=[]): > + if type(rsp) == list: > + i = 0 > + for item in rsp: > + if prefix == []: > + prefix = ['item'] > + print_response(item, prefix[:-1] + ['%s[%d]' % (prefix[-1], i)]) > + i += 1 > + elif type(rsp) == dict: > + for key in rsp.keys(): > + print_response(rsp[key], prefix + [key]) > + else: > + if len(prefix): > + print '%s: %s' % ('.'.join(prefix), rsp) > + else: > + print '%s' % (rsp) > + > +def main(args): > + path = None > + > + # Use QMP_PATH if it's set > + if os.environ.has_key('QMP_PATH'): > + path = os.environ['QMP_PATH'] > + > + while len(args): > + arg = args[0] > + > + if arg.startswith('--'): > + arg = arg[2:] > + if arg.find('=') == -1: > + value = True > + else: > + arg, value = arg.split('=', 1) > + > + if arg in ['path']: > + path = value > + elif arg in ['help']: > + os.execlp('man', 'man', 'qmp') > + else: > + print 'Unknown argument "%s"' % arg > + > + args = args[1:] > + else: > + break > + > + if not path: > + print "QMP path isn't set, use --path or set QMP_PATH" > + return 1 > + > + command, args = args[0], args[1:] > + > + if command in ['help']: > + os.execlp('man', 'man', 'qmp') > + > + srv = QEMUMonitorProtocol(path) > + srv.connect() > + > + def do_command(srv, cmd, **kwds): > + rsp = srv.cmd(cmd, kwds) > + if rsp.has_key('error'): > + raise Exception(rsp['error']['desc']) > + return rsp['return'] > + > + commands = map(lambda x: x['name'], do_command(srv, 'query-commands')) > + > + srv.close() > + > + if command not in commands: > + fullcmd = 'qmp-%s' % command > + try: > + os.environ['QMP_PATH'] = path > + os.execvp(fullcmd, [fullcmd] + args) > + except OSError, (errno, msg): > + if errno == 2: > + print 'Command "%s" not found.' % (fullcmd) > + return 1 > + raise > + return 0 > + > + srv = QEMUMonitorProtocol(path) > + srv.connect() > + > + arguments = {} > + for arg in args: > + if not arg.startswith('--'): > + print 'Unknown argument "%s"' % arg > + return 1 > + > + arg = arg[2:] > + if arg.find('=') == -1: > + value = True > + else: > + arg, value = arg.split('=', 1) > + > + if arg in ['help']: > + os.execlp('man', 'man', 'qmp-%s' % command) > + return 1 > + > + arguments[arg] = value > + > + rsp = do_command(srv, command, **arguments) > + print_response(rsp) > + > +if __name__ == '__main__': > + sys.exit(main(sys.argv[1:]))