[libvirt] [PATCH] Add test case for parsing JSON docs

While investigating some memory leaks it was unclear whether the JSON code correctly free'd all memory during parsing. Add a test case which can be run under valgrind to clearly demonstrate that the parser is leak free. * tests/Makefile.am: Add 'jsontest' * tests/jsontest.c: A few simple JSON parsing tests --- tests/Makefile.am | 14 +++++++ tests/jsontest.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 tests/jsontest.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 7db9d1f..3bde22e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,6 +14,7 @@ INCLUDES = \ $(SASL_CFLAGS) \ $(SELINUX_CFLAGS) \ $(APPARMOR_CFLAGS) \ + $(YAJL_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(WARN_CFLAGS) @@ -29,6 +30,7 @@ LDADDS = \ $(SASL_LIBS) \ $(SELINUX_LIBS) \ $(APPARMOR_LIBS) \ + $(YAJL_LIBS) \ $(WARN_CFLAGS) \ ../src/libvirt_test.la \ ../gnulib/lib/libgnu.la \ @@ -112,6 +114,10 @@ if WITH_CIL check_PROGRAMS += object-locking endif +if HAVE_YAJL +check_PROGRAMS += jsontest +endif + check_PROGRAMS += networkxml2xmltest check_PROGRAMS += networkxml2argvtest @@ -195,6 +201,10 @@ TESTS = virshtest \ virnetsockettest \ $(test_scripts) +if HAVE_YAJL +TESTS += jsontest +endif + if WITH_XEN TESTS += xml2sexprtest \ sexpr2xmltest \ @@ -443,6 +453,10 @@ hashtest_SOURCES = \ hashtest.c hashdata.h testutils.h testutils.c hashtest_LDADD = $(LDADDS) +jsontest_SOURCES = \ + jsontest.c jsondata.h testutils.h testutils.c +jsontest_LDADD = $(LDADDS) + if WITH_LIBVIRTD eventtest_SOURCES = \ eventtest.c testutils.h testutils.c diff --git a/tests/jsontest.c b/tests/jsontest.c new file mode 100644 index 0000000..412f475 --- /dev/null +++ b/tests/jsontest.c @@ -0,0 +1,111 @@ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "internal.h" +#include "json.h" +#include "testutils.h" + +struct testInfo { + const char *doc; + bool pass; +}; + + +static int +testJSONFromString(const void *data) +{ + const struct testInfo *info = data; + virJSONValuePtr json; + int ret = -1; + + json = virJSONValueFromString(info->doc); + + if (info->pass) { + if (!json) { + if (virTestGetVerbose()) + fprintf(stderr, "Fail to parse %s\n", info->doc); + ret = -1; + goto cleanup; + } else { + if (virTestGetDebug()) + fprintf(stderr, "Parsed %s\n", info->doc); + } + } else { + if (json) { + if (virTestGetVerbose()) + fprintf(stderr, "Should not have parsed %s\n", info->doc); + ret = -1; + goto cleanup; + } else { + if (virTestGetDebug()) + fprintf(stderr, "Fail to parse %s\n", info->doc); + } + } + + ret = 0; + +cleanup: + virJSONValueFree(json); + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + +#define DO_TEST_FULL(name, cmd, doc, pass) \ + do { \ + struct testInfo info = { doc, pass }; \ + if (virtTestRun(name, 1, testJSON ## cmd, &info) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST_PARSE(name, doc) \ + DO_TEST_FULL(name, FromString, doc, true) + + DO_TEST_PARSE("Simple", "{\"return\": {}, \"id\": \"libvirt-1\"}"); + DO_TEST_PARSE("NotSoSimple", "{\"QMP\": {\"version\": {\"qemu\":" + "{\"micro\": 91, \"minor\": 13, \"major\": 0}," + "\"package\": \" (qemu-kvm-devel)\"}, \"capabilities\": []}}"); + + + DO_TEST_PARSE("Harder", "{\"return\": [{\"filename\": " + "\"unix:/home/berrange/.libvirt/qemu/lib/tck.monitor,server\"," + "\"label\": \"charmonitor\"}, {\"filename\": \"pty:/dev/pts/158\"," + "\"label\": \"charserial0\"}], \"id\": \"libvirt-3\"}"); + + DO_TEST_PARSE("VeryHard", "{\"return\": [{\"name\": \"quit\"}, {\"name\":" + "\"eject\"}, {\"name\": \"change\"}, {\"name\": \"screendump\"}," + "{\"name\": \"stop\"}, {\"name\": \"cont\"}, {\"name\": " + "\"system_reset\"}, {\"name\": \"system_powerdown\"}, " + "{\"name\": \"device_add\"}, {\"name\": \"device_del\"}, " + "{\"name\": \"cpu\"}, {\"name\": \"memsave\"}, {\"name\": " + "\"pmemsave\"}, {\"name\": \"migrate\"}, {\"name\": " + "\"migrate_cancel\"}, {\"name\": \"migrate_set_speed\"}," + "{\"name\": \"client_migrate_info\"}, {\"name\": " + "\"migrate_set_downtime\"}, {\"name\": \"netdev_add\"}, " + "{\"name\": \"netdev_del\"}, {\"name\": \"block_resize\"}," + "{\"name\": \"balloon\"}, {\"name\": \"set_link\"}, {\"name\":" + "\"getfd\"}, {\"name\": \"closefd\"}, {\"name\": \"block_passwd\"}," + "{\"name\": \"set_password\"}, {\"name\": \"expire_password\"}," + "{\"name\": \"qmp_capabilities\"}, {\"name\": " + "\"human-monitor-command\"}, {\"name\": \"query-version\"}," + "{\"name\": \"query-commands\"}, {\"name\": \"query-chardev\"}," + "{\"name\": \"query-block\"}, {\"name\": \"query-blockstats\"}, " + "{\"name\": \"query-cpus\"}, {\"name\": \"query-pci\"}, {\"name\":" + "\"query-kvm\"}, {\"name\": \"query-status\"}, {\"name\": " + "\"query-mice\"}, {\"name\": \"query-vnc\"}, {\"name\": " + "\"query-spice\"}, {\"name\": \"query-name\"}, {\"name\": " + "\"query-uuid\"}, {\"name\": \"query-migrate\"}, {\"name\": " + "\"query-balloon\"}], \"id\": \"libvirt-2\"}"); + + return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN(mymain) -- 1.7.4.4

On 06/30/2011 08:10 AM, Daniel P. Berrange wrote:
While investigating some memory leaks it was unclear whether the JSON code correctly free'd all memory during parsing. Add a test case which can be run under valgrind to clearly demonstrate that the parser is leak free.
* tests/Makefile.am: Add 'jsontest' * tests/jsontest.c: A few simple JSON parsing tests --- tests/Makefile.am | 14 +++++++ tests/jsontest.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 tests/jsontest.c
Well worth having. ACK. However, I have a concern that will probably entail a followup patch:
@@ -443,6 +453,10 @@ hashtest_SOURCES = \ hashtest.c hashdata.h testutils.h testutils.c hashtest_LDADD = $(LDADDS)
+jsontest_SOURCES = \ + jsontest.c jsondata.h testutils.h testutils.c +jsontest_LDADD = $(LDADDS) + if WITH_LIBVIRTD eventtest_SOURCES = \ eventtest.c testutils.h testutils.c
We have a discrepancy here. The rule for jsontest_SOURCES is unconditional, even though jsontest is only compiled if HAVE_YAJL. Meanwhile, eventtest_SOURCES is conditional on the same WITH_LIBVIRTD as the compilation of eventtest. Yet I don't see any EXTRA_DIST that mentions either jsontest.c or eventtest.c if the two conditions are not met. We need to make sure that automake includes both jsontest.c and eventtest.c in the tarball, regardless of the configure conditionals. We also need to make sure that automake does not try to compile jsontest.c if HAVE_YAJL is false. I haven't yet tested this, but think that this implies some cleanup work is needed in tests/Makefile.am. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

At 06/30/2011 10:10 PM, Daniel P. Berrange Write:
While investigating some memory leaks it was unclear whether the JSON code correctly free'd all memory during parsing. Add a test case which can be run under valgrind to clearly demonstrate that the parser is leak free.
* tests/Makefile.am: Add 'jsontest' * tests/jsontest.c: A few simple JSON parsing tests --- tests/Makefile.am | 14 +++++++ tests/jsontest.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 tests/jsontest.c
diff --git a/tests/Makefile.am b/tests/Makefile.am index 7db9d1f..3bde22e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,6 +14,7 @@ INCLUDES = \ $(SASL_CFLAGS) \ $(SELINUX_CFLAGS) \ $(APPARMOR_CFLAGS) \ + $(YAJL_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(WARN_CFLAGS)
@@ -29,6 +30,7 @@ LDADDS = \ $(SASL_LIBS) \ $(SELINUX_LIBS) \ $(APPARMOR_LIBS) \ + $(YAJL_LIBS) \ $(WARN_CFLAGS) \ ../src/libvirt_test.la \ ../gnulib/lib/libgnu.la \ @@ -112,6 +114,10 @@ if WITH_CIL check_PROGRAMS += object-locking endif
+if HAVE_YAJL +check_PROGRAMS += jsontest +endif + check_PROGRAMS += networkxml2xmltest
check_PROGRAMS += networkxml2argvtest @@ -195,6 +201,10 @@ TESTS = virshtest \ virnetsockettest \ $(test_scripts)
+if HAVE_YAJL +TESTS += jsontest +endif + if WITH_XEN TESTS += xml2sexprtest \ sexpr2xmltest \ @@ -443,6 +453,10 @@ hashtest_SOURCES = \ hashtest.c hashdata.h testutils.h testutils.c hashtest_LDADD = $(LDADDS)
+jsontest_SOURCES = \ + jsontest.c jsondata.h testutils.h testutils.c
jsondata.h does not exist. It will break building.
From 5d8ba96b29df4276fb0a81e10d65fef919789d65 Mon Sep 17 00:00:00 2001 From: Wen Congyang <wency@cn.fujitsu.com> Date: Fri, 1 Jul 2011 10:43:39 +0800 Subject: [PATCH] fix builing error while enabling json
--- tests/Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 38a353f..5d1efb3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -455,7 +455,7 @@ hashtest_SOURCES = \ hashtest_LDADD = $(LDADDS) jsontest_SOURCES = \ - jsontest.c jsondata.h testutils.h testutils.c + jsontest.c testutils.h testutils.c jsontest_LDADD = $(LDADDS) if WITH_LIBVIRTD -- 1.7.1
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Wen Congyang