libvirt/tests/networkxml2conftest.c
Michal Privoznik 5c98d1cee0 virdnsmasq: Lookup DNSMASQ in PATH
While it's true that our virCommand subsystem is happy with
non-absolute paths, the dnsmasq capability code is not. It stores
the path to dnsmasq within and makes it accessible via
dnsmasqCapsGetBinaryPath(). While strictly speaking no caller
necessarily needs canonicalized path, let's find dnsmasq once and
cache the result.

Therefore, when constructing the capabilities structure look up
the binary path. If DNSMASQ already contains an absolute path
then virFindFileInPath() will simply return a copy.

With this code in place, the virFileIsExecutable() check can be
removed from dnsmasqCapsRefreshInternal() because
virFindFileInPath() already made sure the binary is executable.

But introducing virFindFileInPath() means we have to mock it in
test suite because dnsmasqCaps are created in
networkxml2conftest.

Moreover, we don't need to check for dnsmasq in configure.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2022-01-18 15:19:47 +01:00

163 lines
4.6 KiB
C

#include <config.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include "internal.h"
#include "testutils.h"
#include "network_conf.h"
#include "vircommand.h"
#include "viralloc.h"
#include "network/bridge_driver.h"
#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_NONE
static int
testCompareXMLToConfFiles(const char *inxml, const char *outconf,
char *outhostsfile, dnsmasqCaps *caps)
{
char *confactual = NULL;
g_autofree char *hostsfileactual = NULL;
int ret = -1;
virNetworkDef *def = NULL;
virNetworkObj *obj = NULL;
g_autofree char *pidfile = NULL;
g_autoptr(dnsmasqContext) dctx = NULL;
g_autoptr(virNetworkXMLOption) xmlopt = NULL;
if (!(xmlopt = networkDnsmasqCreateXMLConf()))
goto fail;
if (!(def = virNetworkDefParseFile(inxml, xmlopt)))
goto fail;
if (!(obj = virNetworkObjNew()))
goto fail;
virNetworkObjSetDef(obj, def);
dctx = dnsmasqContextNew(def->name, "/var/lib/libvirt/dnsmasq");
if (dctx == NULL)
goto fail;
if (networkDnsmasqConfContents(obj, pidfile, &confactual,
&hostsfileactual, dctx, caps) < 0)
goto fail;
/* Any changes to this function ^^ should be reflected here too. */
#ifndef __linux__
char * tmp;
if (!(tmp = virStringReplace(confactual,
"except-interface=lo0\n",
"except-interface=lo\n")))
goto fail;
VIR_FREE(confactual);
confactual = g_steal_pointer(&tmp);
#endif
if (virTestCompareToFile(confactual, outconf) < 0)
goto fail;
if (virFileExists(outhostsfile)) {
if (!hostsfileactual) {
VIR_TEST_DEBUG("%s: hostsfile exists but the configuration did "
"not specify any host", outhostsfile);
goto fail;
} else if (virTestCompareToFile(hostsfileactual, outhostsfile) < 0) {
goto fail;
}
} else if (hostsfileactual) {
VIR_TEST_DEBUG("%s: file does not exist but actual data was expected",
outhostsfile);
goto fail;
}
ret = 0;
fail:
VIR_FREE(confactual);
virNetworkObjEndAPI(&obj);
return ret;
}
typedef struct {
const char *name;
dnsmasqCaps *caps;
} testInfo;
static int
testCompareXMLToConfHelper(const void *data)
{
int result = -1;
const testInfo *info = data;
g_autofree char *inxml = NULL;
g_autofree char *outconf = NULL;
g_autofree char *outhostsfile = NULL;
inxml = g_strdup_printf("%s/networkxml2confdata/%s.xml", abs_srcdir, info->name);
outconf = g_strdup_printf("%s/networkxml2confdata/%s.conf", abs_srcdir, info->name);
outhostsfile = g_strdup_printf("%s/networkxml2confdata/%s.hostsfile", abs_srcdir, info->name);
result = testCompareXMLToConfFiles(inxml, outconf, outhostsfile, info->caps);
return result;
}
static int
mymain(void)
{
int ret = 0;
g_autoptr(dnsmasqCaps) full = NULL;
full = dnsmasqCapsNewFromBuffer("Dnsmasq version 2.67");
#define DO_TEST(xname, xcaps) \
do { \
static testInfo info; \
\
info.name = xname; \
info.caps = xcaps; \
if (virTestRun("Network XML-2-Conf " xname, \
testCompareXMLToConfHelper, &info) < 0) { \
ret = -1; \
} \
} while (0)
DO_TEST("isolated-network", full);
DO_TEST("netboot-network", full);
DO_TEST("netboot-proxy-network", full);
DO_TEST("nat-network-dns-srv-record-minimal", full);
DO_TEST("nat-network-name-with-quotes", full);
DO_TEST("routed-network", full);
DO_TEST("routed-network-no-dns", full);
DO_TEST("open-network", full);
DO_TEST("nat-network", full);
DO_TEST("nat-network-dns-txt-record", full);
DO_TEST("nat-network-dns-srv-record", full);
DO_TEST("nat-network-dns-hosts", full);
DO_TEST("nat-network-dns-forward-plain", full);
DO_TEST("nat-network-dns-forwarders", full);
DO_TEST("nat-network-dns-forwarder-no-resolv", full);
DO_TEST("nat-network-dns-local-domain", full);
DO_TEST("nat-network-mtu", full);
DO_TEST("dhcp6-network", full);
DO_TEST("dhcp6-nat-network", full);
DO_TEST("dhcp6host-routed-network", full);
DO_TEST("ptr-domains-auto", full);
DO_TEST("dnsmasq-options", full);
DO_TEST("leasetime-seconds", full);
DO_TEST("leasetime-minutes", full);
DO_TEST("leasetime-hours", full);
DO_TEST("leasetime-infinite", full);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
VIR_TEST_MAIN_PRELOAD(mymain,
VIR_TEST_MOCK("virdnsmasq"))