On Mon, Jun 13, 2011 at 06:55:03PM +0200, Michal Novotny wrote:
The regression testing done by comparison of command-line
generated from the network XML file and the expected
command-line arguments (read from file).
For the tests the pidfile should be set to NULL string, i.e.
(null) since no real invocation of the command is being done,
just the command-line is being generated and compared to the
expected one.
[...]
--- /dev/null
+++ b/tests/networkxml2argvtest.c
@@ -0,0 +1,99 @@
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "internal.h"
+#include "testutils.h"
+#include "network_conf.h"
+#include "command.h"
+#include "memory.h"
+#include "network/bridge_driver.h"
+
+static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
+ char *inXmlData = NULL;
+ char *outArgvData = NULL;
+ char *actual = NULL;
+ int ret = -1;
+ virNetworkDefPtr dev = NULL;
+ virNetworkObjPtr obj = NULL;
+ virCommandPtr cmd = NULL;
+ char *pidfile = NULL;
+
+ if (virtTestLoadFile(inxml, &inXmlData) < 0)
+ goto fail;
+
+ if (virtTestLoadFile(outargv, &outArgvData) < 0)
+ goto fail;
+
+ if (!(dev = virNetworkDefParseString(inXmlData)))
+ goto fail;
+
+ if (VIR_ALLOC(obj) < 0)
+ goto fail;
+
+ obj->def = dev;
+
+ if (networkBuildDhcpDaemonCommandLine(obj, &cmd, pidfile) != 0)
+ goto fail;
+
+ if (!(actual = virCommandToString(cmd)))
+ goto fail;
+
+ if (STRNEQ(outArgvData, actual)) {
+ virtTestDifference(stderr, outArgvData, actual);
+ goto fail;
+ }
+
+ ret = 0;
+
+ fail:
+ free(actual);
+ VIR_FREE(pidfile);
+ virCommandFree(cmd);
+ virNetworkObjFree(obj);
+ return ret;
+}
+
+static int testCompareXMLToArgvHelper(const void *data) {
+ char inxml[PATH_MAX];
+ char outargv[PATH_MAX];
+ snprintf(inxml, PATH_MAX, "%s/networkxml2argvdata/%s.xml",
+ abs_srcdir, (const char*)data);
+ snprintf(outargv, PATH_MAX, "%s/networkxml2argvdata/%s.argv",
+ abs_srcdir, (const char*)data);
+ return testCompareXMLToArgvFiles(inxml, outargv);
+}
+
+
+static int
+mymain(void)
+{
+ int ret = 0;
+ char cwd[PATH_MAX];
+
+ abs_srcdir = getenv("abs_srcdir");
+ if (!abs_srcdir)
+ abs_srcdir = getcwd(cwd, sizeof(cwd));
+
+#define DO_TEST(name) \
+ if (virtTestRun("Network XML-2-Argv " name, \
+ 1, testCompareXMLToArgvHelper, (name)) < 0) \
+ ret = -1
+
+ DO_TEST("isolated-network");
+ DO_TEST("routed-network");
+ DO_TEST("nat-network");
+ DO_TEST("netboot-network");
+ DO_TEST("netboot-proxy-network");
+ DO_TEST("nat-network-dns-txt-record");
+
+ return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+VIRT_TEST_MAIN(mymain)
I like the idea of adding more tests but in my case this is crashing
with a memory error. Running under valgrind I get:
paphio:~/libvirt/tests -> valgrind ./networkxml2argvtest
TEST: networkxml2argvtest
..==1582== Source and destination overlap in memcpy(0x7feffc660,
0x7feffc660, 35)
==1582== at 0x4A073BA: memcpy (mc_replace_strmem.c:602)
==1582== by 0x4FC4F0: safe_copy (strerror_r.c:103)
==1582== by 0x4FC5FC: rpl_strerror_r (strerror_r.c:155)
==1582== by 0x4256A6: virStrerror (virterror.c:1239)
==1582== by 0x42577A: virReportSystemErrorFull (virterror.c:1268)
==1582== by 0x417C1E: hostsfileSave (dnsmasq.c:215)
==1582== by 0x417EB8: dnsmasqSave (dnsmasq.c:313)
==1582== by 0x409A2E: networkSaveDnsmasqHostsfile
(bridge_driver.c:453)
==1582== by 0x409FE1: networkBuildDnsmasqArgv (bridge_driver.c:603)
==1582== by 0x40A23C: networkBuildDhcpDaemonCommandLine
(bridge_driver.c:667)
==1582== by 0x40765E: testCompareXMLToArgvFiles
(networkxml2argvtest.c:42)
==1582== by 0x4077AC: testCompareXMLToArgvHelper
(networkxml2argvtest.c:70)
==1582== by 0x407D0F: virtTestRun (testutils.c:134)
==1582== by 0x407885: mymain (networkxml2argvtest.c:91)
==1582== by 0x408ACA: virtTestMain (testutils.c:619)
==1582== by 0x40795F: main (networkxml2argvtest.c:99)
==1582==
!..!==1582== Invalid free() / delete / delete[]
==1582== at 0x4A05187: free (vg_replace_malloc.c:325)
==1582== by 0x41C45E: virFree (memory.c:310)
==1582== by 0x408ADD: virtTestMain (testutils.c:623)
==1582== by 0x40795F: main (networkxml2argvtest.c:99)
==1582== Address 0x7feffee50 is not stack'd, malloc'd or (recently)
free'd
==1582==
6 FAIL
paphio:~/libvirt/tests ->
So two of the tests are failing here, and each of them seems to lead to
a different issue for valgrind. The basic problem is that we seems
to end up in hostsfileSave() within dnsmasq.c with a system path:
Breakpoint 1, hostsfileSave (hostsfile=0x865260) at util/dnsmasq.c:210
210 {
(gdb) p *hostsfile
$2 = {nhosts = 2, hosts = 0x862690,
path = 0x862b40 "/var/lib/libvirt/dnsmasq/default.hostsfile"}
(gdb) n
211 int err = hostsfileWrite(hostsfile->path, hostsfile->hosts,
(gdb) n
214 if (err < 0) {
(gdb) p err
$3 = -13
(gdb)
and then in the end abs_srcdir_cleanup is set but when doing
VIR_FREE(abs_srcdir); in testutils.c:622 it explodes due to an invalid
address...
I'm a bit puzzled about what's ahppening in the first error,
so we call virReportSystemErrorFull, normal, then first thing it does is
char strerror_buf[1024];
const char *errnoDetail = virStrerror(theerrno, strerror_buf,
sizeof(strerror_buf));
which then jump into strerror_r and other code from gnulib I guess
and that fails with valgrind.
There is something fishy here, but what exactly ?!?
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit
http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/