qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
Date: Tue, 08 Nov 2011 07:57:40 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.21) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13

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 <module>
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 "<string>", 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 <module>
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<address@hidden>
---
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<address@hidden>
+#
+# 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:]))






reply via email to

[Prev in Thread] Current Thread [Next in Thread]