[libvirt] [PATCH 3/4] virnetdevbandwidthtest: Introduce mocking

Michal Privoznik mprivozn at redhat.com
Thu Jan 23 13:44:39 UTC 2014


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 at redhat.com>
---
 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 at redhat.com>
+ */
+
+#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




More information about the libvir-list mailing list