From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=46790 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PyMvT-0000ui-Lp for qemu-devel@nongnu.org; Sat, 12 Mar 2011 06:24:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PyMvS-0004DW-37 for qemu-devel@nongnu.org; Sat, 12 Mar 2011 06:24:03 -0500 Received: from mail-vw0-f45.google.com ([209.85.212.45]:50278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PyMvR-0004DB-S7 for qemu-devel@nongnu.org; Sat, 12 Mar 2011 06:24:02 -0500 Received: by vws17 with SMTP id 17so1450184vws.4 for ; Sat, 12 Mar 2011 03:24:01 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <1299884745-521-15-git-send-email-aliguori@us.ibm.com> References: <1299884745-521-1-git-send-email-aliguori@us.ibm.com> <1299884745-521-15-git-send-email-aliguori@us.ibm.com> From: Blue Swirl Date: Sat, 12 Mar 2011 13:23:41 +0200 Message-ID: Subject: Re: [Qemu-devel] [PATCH 14/15] qapi: add test-libqmp Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Markus Armbruster , Avi Kivity , Luiz Capitulino , qemu-devel@nongnu.org, Adam Litke On Sat, Mar 12, 2011 at 1:05 AM, Anthony Liguori wrot= e: > This provides a glib-test based testing framework for QMP > > Signed-off-by: Anthony Liguori > > diff --git a/Makefile b/Makefile > index 5170675..1d363d7 100644 > --- a/Makefile > +++ b/Makefile > @@ -72,6 +72,8 @@ defconfig: > > =C2=A0-include config-all-devices.mak > > +TOOLS +=3D test-libqmp > + > =C2=A0build-all: $(DOCS) $(TOOLS) recurse-all > > =C2=A0config-host.h: config-host.h-timestamp > @@ -205,6 +207,15 @@ check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PR= OG_DEPS) > =C2=A0check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) > =C2=A0check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.= o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_D= EPS) > > +LIBQMP_OBJS :=3D qmp-types.o libqmp.o error.o libqmp-core.o > +LIBQMP_OBJS +=3D qmp-marshal-types-core.o qmp-marshal-types.o > +LIBQMP_OBJS +=3D qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson= .o > +LIBQMP_OBJS +=3D qerror.o > +LIBQMP_OBJS +=3D json-streamer.o json-lexer.o json-parser.o > +LIBQMP_OBJS +=3D $(oslib-obj-y) $(trace-obj-y) qemu-malloc.o > + > +test-libqmp: test-libqmp.o $(LIBQMP_OBJS) qemu-timer-common.o > + > =C2=A0clean: > =C2=A0# avoid old build problems by removing potentially incorrect old fi= les > =C2=A0 =C2=A0 =C2=A0 =C2=A0rm -f config.mak op-i386.h opc-i386.h gen-op-i= 386.h op-arm.h opc-arm.h gen-op-arm.h > diff --git a/test-libqmp.c b/test-libqmp.c > new file mode 100644 I'd put this to tests/. > index 0000000..9b73987 > --- /dev/null > +++ b/test-libqmp.c > @@ -0,0 +1,170 @@ > +/* > + * QAPI > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * =C2=A0Anthony Liguori =C2=A0 > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. =C2= =A0See > + * the COPYING.LIB file in the top-level directory. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "config-host.h" > +#include "libqmp.h" > +#include "qerror.h" > + > +#define g_assert_noerr(err) g_assert(err =3D=3D NULL); > +#define g_assert_anyerr(err) g_assert(err !=3D NULL); > +#define g_assert_cmperr(err, op, type) do { =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \ > + =C2=A0 =C2=A0g_assert_anyerr(err); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\ > + =C2=A0 =C2=A0g_assert_cmpstr(error_get_field(err, "class"), op, type); = \ > +} while (0) > + > +static pid_t last_qemu_pid =3D -1; > + > +static QmpSession *qemu(const char *fmt, ...) > +{ > + =C2=A0 =C2=A0char buffer0[4096]; > + =C2=A0 =C2=A0char buffer1[4096]; > + =C2=A0 =C2=A0const char *pid_filename =3D "/tmp/test-libqmp-qemu.pid"; > + =C2=A0 =C2=A0const char *path =3D "/tmp/test-libqmp-qemu.sock"; Very insecure filenames. > + =C2=A0 =C2=A0struct sockaddr_un addr; > + =C2=A0 =C2=A0va_list ap; > + =C2=A0 =C2=A0int ret; > + =C2=A0 =C2=A0int fd; > + > + =C2=A0 =C2=A0va_start(ap, fmt); > + =C2=A0 =C2=A0vsnprintf(buffer0, sizeof(buffer0), fmt, ap); > + =C2=A0 =C2=A0va_end(ap); > + > + =C2=A0 =C2=A0snprintf(buffer1, sizeof(buffer1), > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "i386-softmmu/qemu " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-enable-kvm " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-name test-libqmp " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-qmp2 qmp " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-chardev socket,id=3Dqmp,pat= h=3D%s,server=3Don,wait=3Doff " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-vnc none " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-daemonize " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "-pidfile %s " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "%s", path, pid_filename, buf= fer0); > + =C2=A0 =C2=A0g_test_message("Executing %s\n", buffer1); > + =C2=A0 =C2=A0ret =3D system(buffer1); > + =C2=A0 =C2=A0g_assert(ret !=3D -1); > + > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0FILE *f; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0char buffer[1024]; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0char *ptr; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f =3D fopen(pid_filename, "r"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0g_assert(f !=3D NULL); > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0ptr =3D fgets(buffer, sizeof(buffer), f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0g_assert(ptr !=3D NULL); > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(f); > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0last_qemu_pid =3D atoi(buffer); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0fd =3D socket(PF_UNIX, SOCK_STREAM, 0); > + =C2=A0 =C2=A0g_assert(fd !=3D -1); > + > + =C2=A0 =C2=A0addr.sun_family =3D AF_UNIX; > + =C2=A0 =C2=A0snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path)= ; > + =C2=A0 =C2=A0ret =3D connect(fd, (struct sockaddr *)&addr, sizeof(addr)= ); > + =C2=A0 =C2=A0g_assert(ret !=3D -1); > + > + =C2=A0 =C2=A0return qmp_session_new(fd); > +} > + > +static void wait_for_pid_exit(pid_t pid) > +{ > + =C2=A0 =C2=A0FILE *f =3D NULL; > + > + =C2=A0 =C2=A0/* This is ugly but I don't know of a better way */ man waitpid? > + =C2=A0 =C2=A0do { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0char buffer[1024]; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fclose(f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0usleep(10000); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0snprintf(buffer, sizeof(buffer), "/proc/%d/s= tat", pid); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f =3D fopen(buffer, "r"); > + =C2=A0 =C2=A0} while (f); > +} > + > +static void qemu_destroy(QmpSession *sess) > +{ > + =C2=A0 =C2=A0wait_for_pid_exit(last_qemu_pid); > + =C2=A0 =C2=A0last_qemu_pid =3D -1; > + =C2=A0 =C2=A0qmp_session_destroy(sess); > +} > + > +static void test_version(void) > +{ > + =C2=A0 =C2=A0QmpSession *sess =3D NULL; > + =C2=A0 =C2=A0VersionInfo *info; > + =C2=A0 =C2=A0char version[1024]; > + =C2=A0 =C2=A0char *ptr, *end; > + =C2=A0 =C2=A0int major, minor, micro; > + > + =C2=A0 =C2=A0/* Even though we use the same string as the source input,= we do parse it > + =C2=A0 =C2=A0 * a little bit different for no other reason that to make= sure we catch > + =C2=A0 =C2=A0 * potential bugs. > + =C2=A0 =C2=A0 */ > + =C2=A0 =C2=A0snprintf(version, sizeof(version), "%s", QEMU_VERSION); > + =C2=A0 =C2=A0ptr =3D version; > + > + =C2=A0 =C2=A0end =3D strchr(ptr, '.'); > + =C2=A0 =C2=A0g_assert(end !=3D NULL); > + =C2=A0 =C2=A0*end =3D 0; > + =C2=A0 =C2=A0major =3D atoi(ptr); strtoll(), also below. > + =C2=A0 =C2=A0ptr =3D end + 1; > + > + =C2=A0 =C2=A0end =3D strchr(ptr, '.'); > + =C2=A0 =C2=A0g_assert(end !=3D NULL); > + =C2=A0 =C2=A0*end =3D 0; > + =C2=A0 =C2=A0minor =3D atoi(ptr); > + =C2=A0 =C2=A0ptr =3D end + 1; > + > + =C2=A0 =C2=A0micro =3D atoi(ptr); > + =C2=A0 =C2=A0while (g_ascii_isdigit(*ptr)) ptr++; > + > + =C2=A0 =C2=A0sess =3D qemu("-S"); > + > + =C2=A0 =C2=A0info =3D libqmp_query_version(sess, NULL); > + > + =C2=A0 =C2=A0g_assert_cmpint(major, =3D=3D, info->qemu.major); > + =C2=A0 =C2=A0g_assert_cmpint(minor, =3D=3D, info->qemu.minor); > + =C2=A0 =C2=A0g_assert_cmpint(micro, =3D=3D, info->qemu.micro); > + =C2=A0 =C2=A0g_assert_cmpstr(ptr, =3D=3D, info->package); > + > + =C2=A0 =C2=A0qmp_free_version_info(info); > + > + =C2=A0 =C2=A0libqmp_quit(sess, NULL); > + > + =C2=A0 =C2=A0qemu_destroy(sess); > +} > + > +int main(int argc, char **argv) > +{ > + =C2=A0 =C2=A0g_test_init(&argc, &argv, NULL); > + > + =C2=A0 =C2=A0g_test_add_func("/0.14/misc/version", test_version); > + > + =C2=A0 =C2=A0g_test_run(); > + > + =C2=A0 =C2=A0return 0; > +} > -- > 1.7.0.4 > > >