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@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/