The mocking will be used in later commits to mock all calls to the virCommandRun(). This is easier to do than cutting off the command creation and run into two separate pieces. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- tests/Makefile.am | 9 ++++ tests/virnetdevbandwidthmock.c | 106 +++++++++++++++++++++++++++++++++++++++++ tests/virnetdevbandwidthtest.c | 21 +++++++- 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/virnetdevbandwidthmock.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 0930073..f914244 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -319,6 +319,7 @@ test_libraries = libshunload.la \ virnetserverclientmock.la \ vircgroupmock.la \ virpcimock.la \ + virnetdevbandwidthmock.la \ $(NULL) if WITH_QEMU test_libraries += libqemumonitortestutils.la @@ -655,6 +656,14 @@ virnetdevbandwidthtest_SOURCES = \ virnetdevbandwidthtest.c testutils.h testutils.c virnetdevbandwidthtest_LDADD = $(LDADDS) +virnetdevbandwidthmock_la_SOURCES = \ + virnetdevbandwidthmock.c +virnetdevbandwidthmock_la_CFLAGS = $(AM_CFLAGS) +virnetdevbandwidthmock_la_LIBADD = $(GNULIB_LIBS) \ + ../src/libvirt.la +virnetdevbandwidthmock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + if WITH_LIBVIRTD libvirtdconftest_SOURCES = \ libvirtdconftest.c testutils.h testutils.c \ diff --git a/tests/virnetdevbandwidthmock.c b/tests/virnetdevbandwidthmock.c new file mode 100644 index 0000000..8bb590b --- /dev/null +++ b/tests/virnetdevbandwidthmock.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Michal Privoznik <mprivozn@xxxxxxxxxx> + */ + +#include <config.h> + +#include <dlfcn.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include "viralloc.h" +#include "vircommand.h" +#include "virfile.h" + +static int (*realvirCommandRun)(virCommandPtr cmd, int *exitstatus); + +/* Don't make static, since it causes problems with clang + * when passed as an arg to virAsprintf() + * vircgroupmock.c:462:22: error: static variable 'fakesysfsdir' is used in an inline function with external linkage [-Werror,-Wstatic-in-inline] + */ +char *outfile; + +#define STDERR(...) \ + fprintf(stderr, "%s %zu: ", __FUNCTION__, (size_t) __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + +#define ABORT(...) \ + do { \ + STDERR(__VA_ARGS__); \ + abort(); \ + } while (0) + +static void +init(void) +{ + if (outfile) + return; + + if (!(outfile = getenv("LIBVIRT_OUTFILE"))) + ABORT("Missing LIBVIRT_OUTDIR env variable\n"); + +#define LOAD_SYM(name) \ + do { \ + if (!(real ## name = dlsym(RTLD_NEXT, #name))) \ + ABORT("Cannot find real '%s' symbol\n", #name); \ + } while (0) + + LOAD_SYM(virCommandRun); +} + +/* Here we don't really run the command, but instead get its string + * representation which is then written to a temporary file referenced + * by @outfile. + */ +int +virCommandRun(virCommandPtr cmd, int *exitstatus) +{ + int ret = -1; + int fd = 0; + char *buf = NULL; + + if (!outfile) + init(); + + if (!(buf = virCommandToString(cmd))) { + *exitstatus = EXIT_FAILURE; + return 0; + } + + if ((fd = open(outfile, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { + STDERR("unable to open file: %s %d", outfile, errno); + goto cleanup; + } + + if (safewrite(fd, buf, strlen(buf)) < 0 || + safewrite(fd, "\n", 1) < 0) { + STDERR("unable to write to file: %s %d", outfile, errno); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + VIR_FREE(buf); + if (exitstatus) + *exitstatus = ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + return ret; +} diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c index 989018e..09cc2ec 100644 --- a/tests/virnetdevbandwidthtest.c +++ b/tests/virnetdevbandwidthtest.c @@ -103,10 +103,25 @@ cleanup: return ret; } +#define OUTFILETEMPLATE abs_builddir "/virnetdevbandwidthtest-XXXXXX" + static int mymain(void) { int ret = 0; + char *outfile; + + if (VIR_STRDUP_QUIET(outfile, OUTFILETEMPLATE) < 0) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + if (!mktemp(outfile)) { + fprintf(stderr, "Cannot create outfile"); + abort(); + } + + setenv("LIBVIRT_OUTFILE", outfile, 1); #define DO_TEST_MINIMAL(r, ...) \ do { \ @@ -149,7 +164,11 @@ mymain(void) " <inbound average='1' peak='2' floor='3'/>" " <outbound average='5' peak='6'/>" "</bandwidth>"); + + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) + unlink(outfile); + return ret; } -VIRT_TEST_MAIN(mymain); +VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virnetdevbandwidthmock.so") -- 1.8.5.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list