From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:39826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNmBR-0003jU-2a for qemu-devel@nongnu.org; Tue, 08 Nov 2011 08:57:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RNmBM-0006KY-LY for qemu-devel@nongnu.org; Tue, 08 Nov 2011 08:57:48 -0500 Received: from mail-gy0-f173.google.com ([209.85.160.173]:59424) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNmBM-0006KS-FG for qemu-devel@nongnu.org; Tue, 08 Nov 2011 08:57:44 -0500 Received: by gyb11 with SMTP id 11so619132gyb.4 for ; Tue, 08 Nov 2011 05:57:44 -0800 (PST) Message-ID: <4EB93554.9030307@codemonkey.ws> Date: Tue, 08 Nov 2011 07:57:40 -0600 From: Anthony Liguori MIME-Version: 1.0 References: <1320678675-21379-1-git-send-email-aliguori@us.ibm.com> <4EB8EA27.9080902@linux.vnet.ibm.com> In-Reply-To: <4EB8EA27.9080902@linux.vnet.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: Mark Wu Cc: qemu-devel@nongnu.org, Luiz Capitulino On 11/08/2011 02:36 AM, Mark Wu wrote: > 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? Definitely. Could you just send out a version of the patch with your changes, a (v2) in the subject, and your Signed-off-by? Thanks! Regards, Anthony Liguori > > 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:])) > >