[libvirt PATCH v5 23/32] tests: add tests for nbdkit invocation

Jonathon Jongsma jjongsma at redhat.com
Tue Feb 14 17:08:10 UTC 2023


We were testing the arguments that were being passed to qemu when a disk
was being served by nbdkit, but the arguments used to start nbdkit
itself were not testable. This adds a test to ensure that we're invoking
nbdkit correctly for various disk source definitions.

Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
 build-aux/syntax-check.mk                     |   2 +-
 src/qemu/qemu_nbdkit.c                        |   4 +-
 src/qemu/qemu_nbdkitpriv.h                    |  31 ++
 tests/meson.build                             |   1 +
 .../disk-cdrom-network.args.disk0             |   6 +
 .../disk-cdrom-network.args.disk1             |   8 +
 .../disk-cdrom-network.args.disk1.pipe.778    |   1 +
 .../disk-cdrom-network.args.disk2             |   8 +
 .../disk-cdrom-network.args.disk2.pipe.780    |   1 +
 .../disk-network-http.args.disk0              |   6 +
 .../disk-network-http.args.disk1              |   5 +
 .../disk-network-http.args.disk2              |   6 +
 .../disk-network-http.args.disk2.pipe.778     |   1 +
 .../disk-network-http.args.disk3              |   7 +
 .../disk-network-http.args.disk3.pipe.780     |   1 +
 ...work-source-curl-nbdkit-backing.args.disk0 |   7 +
 ...ce-curl-nbdkit-backing.args.disk0.pipe.778 |   1 +
 .../disk-network-source-curl.args.disk0       |   7 +
 ...sk-network-source-curl.args.disk0.pipe.778 |   1 +
 .../disk-network-source-curl.args.disk1       |   7 +
 ...sk-network-source-curl.args.disk1.pipe.780 |   1 +
 .../disk-network-source-curl.args.disk2       |   7 +
 ...sk-network-source-curl.args.disk2.pipe.782 |   1 +
 .../disk-network-source-curl.args.disk3       |   6 +
 .../disk-network-source-curl.args.disk4       |   6 +
 .../disk-network-ssh.args.disk0               |   6 +
 tests/qemunbdkittest.c                        | 300 ++++++++++++++++++
 27 files changed, 436 insertions(+), 2 deletions(-)
 create mode 100644 src/qemu/qemu_nbdkitpriv.h
 create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk0
 create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk1
 create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.778
 create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk2
 create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.780
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk0
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk1
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk2
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.778
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk3
 create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.780
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.778
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk0
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.778
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk1
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.780
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk2
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.782
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk3
 create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk4
 create mode 100644 tests/qemunbdkitdata/disk-network-ssh.args.disk0
 create mode 100644 tests/qemunbdkittest.c

diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index 96d322ee04..48f650c5bd 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -1360,7 +1360,7 @@ exclude_file_name_regexp--sc_prohibit_close = \
   (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/vir(file|event)\.c|src/libvirt-stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c)|tools/nss/libvirt_nss_(leases|macs)\.c)|tools/virt-qemu-qmp-proxy$$)
 
 exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
-  (^tests/(nodedevmdevctl|virhostcpu|virpcitest|virstoragetest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
+  (^tests/(nodedevmdevctl|virhostcpu|virpcitest|virstoragetest|qemunbdkit)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
 
 exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
   (^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)\.c$$)
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index dcdd38d119..e6d3232a1e 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -33,6 +33,8 @@
 #include "qemu_driver.h"
 #include "qemu_extdevice.h"
 #include "qemu_nbdkit.h"
+#define LIBVIRT_QEMU_NBDKITPRIV_H_ALLOW
+#include "qemu_nbdkitpriv.h"
 #include "qemu_security.h"
 
 #include <fcntl.h>
@@ -935,7 +937,7 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
 }
 
 
-static virCommand *
+virCommand *
 qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc)
 {
     g_autoptr(virCommand) cmd = virCommandNewArgList(proc->caps->path,
diff --git a/src/qemu/qemu_nbdkitpriv.h b/src/qemu/qemu_nbdkitpriv.h
new file mode 100644
index 0000000000..64f9bb99d8
--- /dev/null
+++ b/src/qemu/qemu_nbdkitpriv.h
@@ -0,0 +1,31 @@
+/*
+ * qemu_nbdkitpriv.h: exposing some functions for testing
+ *
+ * Copyright (C) 2021 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/>.
+ *
+ */
+
+#ifndef LIBVIRT_QEMU_NBDKITPRIV_H_ALLOW
+# error "qemu_nbdkitpriv.h may only be included by qemu_nbdkit.c or test suites"
+#endif /* LIBVIRT_QEMU_NBDKITPRIV_H_ALLOW */
+
+#pragma once
+
+#include "qemu_nbdkit.h"
+
+virCommand *
+qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc);
diff --git a/tests/meson.build b/tests/meson.build
index 15b049c6ac..67dda415de 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -458,6 +458,7 @@ if conf.has('WITH_QEMU')
     { 'name': 'qemuvhostusertest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_file_wrapper_lib ] },
     { 'name': 'qemuxml2argvtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
     { 'name': 'qemuxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
+    { 'name': 'qemunbdkittest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
   ]
 endif
 
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk0 b/tests/qemunbdkitdata/disk-cdrom-network.args.disk0
new file mode 100644
index 0000000000..b2f3be4cba
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk0
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
+--foreground \
+--readonly curl \
+protocols=ftp \
+url=ftp://host.name:21/url/path/file.iso
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk1 b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
new file mode 100644
index 0000000000..a23f6573d6
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
@@ -0,0 +1,8 @@
+nbdkit \
+--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
+--foreground \
+--readonly curl \
+protocols=ftps \
+url=ftps://host.name:990/url/path/file.iso \
+user=testuser \
+password=-777
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.778 b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.778
new file mode 100644
index 0000000000..ccdd4033fc
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.778
@@ -0,0 +1 @@
+iscsi-mycluster_myname-secret
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk2 b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
new file mode 100644
index 0000000000..04e918609a
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
@@ -0,0 +1,8 @@
+nbdkit \
+--unix /tmp/statedir-2/nbdkit-test-disk-2.socket \
+--foreground \
+--readonly curl \
+protocols=https \
+'url=https://host.name:443/url/path/file.iso?test=val' \
+user=testuser \
+password=-779
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.780 b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.780
new file mode 100644
index 0000000000..ccdd4033fc
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.780
@@ -0,0 +1 @@
+iscsi-mycluster_myname-secret
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk0 b/tests/qemunbdkitdata/disk-network-http.args.disk0
new file mode 100644
index 0000000000..8316f353cb
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk0
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
+--foreground curl \
+protocols=http,https \
+url=http://example.org:80/test.img \
+timeout=1234
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk1 b/tests/qemunbdkitdata/disk-network-http.args.disk1
new file mode 100644
index 0000000000..a546a68b27
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk1
@@ -0,0 +1,5 @@
+nbdkit \
+--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
+--foreground curl \
+protocols=https \
+url=https://example.org:443/test2.img
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk2 b/tests/qemunbdkitdata/disk-network-http.args.disk2
new file mode 100644
index 0000000000..1004547b3a
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk2
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-2/nbdkit-test-disk-2.socket \
+--foreground curl \
+protocols=http,https \
+url=http://example.org:1234/test3.img \
+cookie=-777
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.778 b/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.778
new file mode 100644
index 0000000000..2c42c95930
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.778
@@ -0,0 +1 @@
+test=testcookievalue; test2="blurb"
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk3 b/tests/qemunbdkitdata/disk-network-http.args.disk3
new file mode 100644
index 0000000000..e3c357b89a
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk3
@@ -0,0 +1,7 @@
+nbdkit \
+--unix /tmp/statedir-3/nbdkit-test-disk-3.socket \
+--foreground curl \
+protocols=https \
+'url=https://example.org:1234/test4.img?par=val&other=ble' \
+cookie=-779 \
+sslverify=false
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.780 b/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.780
new file mode 100644
index 0000000000..2c42c95930
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.780
@@ -0,0 +1 @@
+test=testcookievalue; test2="blurb"
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0 b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
new file mode 100644
index 0000000000..605354433b
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
@@ -0,0 +1,7 @@
+nbdkit \
+--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
+--foreground \
+--readonly curl \
+protocols=https \
+url=https://https.example.org:8443/path/to/disk1.qcow2 \
+cookie=-777
diff --git a/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.778 b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.778
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.778
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk0 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
new file mode 100644
index 0000000000..948dbfbe5a
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
@@ -0,0 +1,7 @@
+nbdkit \
+--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
+--foreground \
+--readonly curl \
+protocols=https \
+url=https://https.example.org:8443/path/to/disk1.iso \
+cookie=-777
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.778 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.778
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.778
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk1 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
new file mode 100644
index 0000000000..fde6a4f533
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
@@ -0,0 +1,7 @@
+nbdkit \
+--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
+--foreground curl \
+protocols=https \
+'url=https://https.example.org:8443/path/to/disk5.iso?foo=bar' \
+cookie=-779 \
+sslverify=false
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.780 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.780
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.780
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk2 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
new file mode 100644
index 0000000000..88c9fa35a1
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
@@ -0,0 +1,7 @@
+nbdkit \
+--unix /tmp/statedir-2/nbdkit-test-disk-2.socket \
+--foreground \
+--readonly curl \
+protocols=http,https \
+url=http://http.example.org:8080/path/to/disk2.iso \
+cookie=-781
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.782 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.782
new file mode 100644
index 0000000000..5c035e84c5
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.782
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2; cookie3=cookievalue3
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk3 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk3
new file mode 100644
index 0000000000..f517baa948
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk3
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-3/nbdkit-test-disk-3.socket \
+--foreground \
+--readonly curl \
+protocols=ftp \
+url=ftp://ftp.example.org:20/path/to/disk3.iso
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk4 b/tests/qemunbdkitdata/disk-network-source-curl.args.disk4
new file mode 100644
index 0000000000..1df47a9d54
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk4
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-4/nbdkit-test-disk-4.socket \
+--foreground \
+--readonly curl \
+protocols=ftps \
+url=ftps://ftps.example.org:22/path/to/disk4.iso
diff --git a/tests/qemunbdkitdata/disk-network-ssh.args.disk0 b/tests/qemunbdkitdata/disk-network-ssh.args.disk0
new file mode 100644
index 0000000000..c04dc8bb03
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-ssh.args.disk0
@@ -0,0 +1,6 @@
+nbdkit \
+--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
+--foreground ssh \
+host=example.org \
+port=2222 \
+path=test.img
diff --git a/tests/qemunbdkittest.c b/tests/qemunbdkittest.c
new file mode 100644
index 0000000000..5606e155eb
--- /dev/null
+++ b/tests/qemunbdkittest.c
@@ -0,0 +1,300 @@
+#include <config.h>
+
+#include <fcntl.h>
+#include "internal.h"
+#include "testutils.h"
+#include "testutilsqemu.h"
+#include "qemu/qemu_domain.h"
+#include "qemu/qemu_nbdkit.h"
+#define LIBVIRT_QEMU_NBDKITPRIV_H_ALLOW
+#include "qemu/qemu_nbdkitpriv.h"
+#include "vircommand.h"
+#define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
+#include "vircommandpriv.h"
+#include "virutil.h"
+#include "virsecret.h"
+#include "datatypes.h"
+#include "virmock.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+static virQEMUDriver driver;
+
+
+/* Some mock implementations for testing */
+#define PIPE_FD_START 777
+static int mockpipefd = PIPE_FD_START;
+
+static int (*real_virPipeQuiet)(int fds[2]);
+static void
+init_syms(void)
+{
+    VIR_MOCK_REAL_INIT(virPipeQuiet);
+}
+
+static int
+moveToStableFd(int fd)
+{
+    int newfd;
+
+    /* don't overwrite an existing fd */
+    if (fcntl(mockpipefd, F_GETFD) != -1)
+        abort();
+
+    newfd = dup2(fd, mockpipefd++);
+
+    VIR_FORCE_CLOSE(fd);
+
+    return newfd;
+}
+
+
+int
+virPipeQuiet(int fds[2])
+{
+    int tempfds[2];
+
+    init_syms();
+
+    if (real_virPipeQuiet(tempfds) < 0)
+        return -1;
+
+    if ((fds[0] = moveToStableFd(tempfds[0])) < 0 ||
+        (fds[1] = moveToStableFd(tempfds[1])) < 0)
+        return -1;
+
+    return 0;
+}
+
+
+int
+virSecretGetSecretString(virConnectPtr conn G_GNUC_UNUSED,
+                         virSecretLookupTypeDef *seclookupdef,
+                         virSecretUsageType secretUsageType,
+                         uint8_t **secret,
+                         size_t *secret_size)
+{
+    char uuidstr[VIR_UUID_BUFLEN];
+    const char *secretname = NULL;
+    char *tmp = NULL;
+
+    switch (seclookupdef->type) {
+        case VIR_SECRET_LOOKUP_TYPE_UUID:
+            virUUIDFormat(seclookupdef->u.uuid, uuidstr);
+            secretname = uuidstr;
+            break;
+        case VIR_SECRET_LOOKUP_TYPE_USAGE:
+            secretname = seclookupdef->u.usage;
+            break;
+        case VIR_SECRET_LOOKUP_TYPE_NONE:
+        case VIR_SECRET_LOOKUP_TYPE_LAST:
+        default:
+            virReportEnumRangeError(virSecretLookupType, seclookupdef->type);
+            return -1;
+    };
+
+    /* For testing, just generate a value for the secret that includes the type
+     * and the id of the secret */
+    tmp = g_strdup_printf("%s-%s-secret", virSecretUsageTypeToString(secretUsageType), secretname);
+    *secret = (uint8_t*)tmp;
+    *secret_size = strlen(tmp) + 1;
+
+    return 0;
+}
+
+virConnectPtr virGetConnectSecret(void)
+{
+    return virGetConnect();
+}
+
+/* end of mock implementations */
+
+
+typedef struct {
+    const char *name;
+    char* infile;
+    char* outtemplate;
+    qemuNbdkitCaps *nbdkitcaps;
+    bool expectFail;
+} TestInfo;
+
+
+typedef enum {
+    NBDKIT_ARG_CAPS,
+    NBDKIT_ARG_EXPECT_FAIL,
+    NBDKIT_ARG_END
+} NbdkitArgName;
+
+
+static void
+testInfoSetPaths(TestInfo *info)
+{
+    info->infile = g_strdup_printf("%s/qemuxml2argvdata/%s.xml",
+                                   abs_srcdir, info->name);
+    info->outtemplate = g_strdup_printf("%s/qemunbdkitdata/%s",
+                                        abs_srcdir, info->name);
+}
+
+static void
+testInfoClear(TestInfo *info)
+{
+    g_free(info->infile);
+    g_free(info->outtemplate);
+    g_clear_object(&info->nbdkitcaps);
+}
+
+static void
+testInfoSetArgs(TestInfo *info, ...)
+{
+    va_list argptr;
+    NbdkitArgName argname;
+    unsigned int cap;
+
+    va_start(argptr, info);
+    while ((argname = va_arg(argptr, NbdkitArgName)) != NBDKIT_ARG_END) {
+        switch (argname) {
+            case NBDKIT_ARG_CAPS:
+                while ((cap = va_arg(argptr, unsigned int)) < QEMU_NBDKIT_CAPS_LAST)
+                    qemuNbdkitCapsSet(info->nbdkitcaps, cap);
+                break;
+            case NBDKIT_ARG_EXPECT_FAIL:
+                info->expectFail = va_arg(argptr, unsigned int);
+                break;
+            case NBDKIT_ARG_END:
+            default:
+                break;
+        }
+    }
+}
+
+
+static int
+testNbdkit(const void *data)
+{
+    const TestInfo *info = data;
+    g_autoptr(virDomainDef) def = NULL;
+    size_t i;
+    int ret = 0;
+
+    /* restart mock pipe fds so tests are consistent */
+    mockpipefd = PIPE_FD_START;
+
+    if (!virFileExists(info->infile)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "Test input file '%s' is missing", info->infile);
+        return -1;
+    }
+
+    if (!(def = virDomainDefParseFile(info->infile, driver.xmlopt, NULL,
+                                      VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
+        return -1;
+
+    for (i = 0; i < def->ndisks; i++) {
+        virDomainDiskDef *disk = def->disks[i];
+        g_autofree char *statedir = g_strdup_printf("/tmp/statedir-%zi", i);
+        g_autofree char *alias = g_strdup_printf("test-disk-%zi", i);
+        g_autofree char *cmdfile = g_strdup_printf("%s.args.disk%zi",
+                                                   info->outtemplate, i);
+
+        if (qemuNbdkitInitStorageSource(info->nbdkitcaps, disk->src, statedir,
+                                        alias, 101, 101)) {
+            qemuDomainStorageSourcePrivate *srcPriv =
+                qemuDomainStorageSourcePrivateFetch(disk->src);
+            g_autoptr(virCommand) cmd = NULL;
+            g_autoptr(virCommandDryRunToken) dryRunToken = virCommandDryRunTokenNew();
+            g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+            g_autofree char *actualCmdline = NULL;
+            virCommandSendBuffer *sendbuffers;
+            int nsendbuffers;
+            size_t j;
+
+            virCommandSetDryRun(dryRunToken, &buf, true, true, NULL, NULL);
+            cmd = qemuNbdkitProcessBuildCommand(srcPriv->nbdkitProcess);
+
+            if (virCommandRun(cmd, NULL) < 0) {
+                ret = -1;
+                continue;
+            }
+            virCommandPeekSendBuffers(cmd, &sendbuffers, &nsendbuffers);
+
+            if (!(actualCmdline = virBufferContentAndReset(&buf))) {
+                ret = -1;
+                continue;
+            }
+
+            if (virTestCompareToFileFull(actualCmdline, cmdfile, false) < 0)
+                ret = -1;
+
+            for (j = 0; j < nsendbuffers; j++) {
+                virCommandSendBuffer *buffer = &sendbuffers[j];
+                g_autofree char *pipefile = g_strdup_printf("%s.pipe.%i",
+                                                            cmdfile,
+                                                            buffer->fd);
+
+                if (virTestCompareToFile((const char*)buffer->buffer, pipefile) < 0)
+                    ret = -1;
+            }
+        } else {
+            if (virFileExists(cmdfile)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               "qemuNbdkitInitStorageSource() was not expected to fail");
+                ret = -1;
+            }
+        }
+    }
+
+    if (info->expectFail) {
+        if (ret == 0) {
+            ret = -1;
+            VIR_TEST_DEBUG("Error expected but there wasn't any.");
+        } else {
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+static int
+mymain(void)
+{
+    int ret = 0;
+
+    if (qemuTestDriverInit(&driver) < 0)
+        return EXIT_FAILURE;
+
+
+#define DO_TEST_FULL(_name, ...) \
+    do { \
+        TestInfo info = { \
+            .name = _name, \
+            .nbdkitcaps = qemuNbdkitCapsNew(TEST_NBDKIT_PATH), \
+        }; \
+        testInfoSetPaths(&info); \
+        testInfoSetArgs(&info, __VA_ARGS__); \
+        virTestRunLog(&ret, "nbdkit " _name, testNbdkit, &info); \
+        testInfoClear(&info); \
+    } while (0)
+
+#define DO_TEST(_name, ...) \
+    DO_TEST_FULL(_name, NBDKIT_ARG_CAPS, __VA_ARGS__, QEMU_NBDKIT_CAPS_LAST, NBDKIT_ARG_END)
+
+#define DO_TEST_FAILURE(_name, ...) \
+    DO_TEST_FULL(_name, \
+                 NBDKIT_ARG_EXPECT_FAIL, 1, \
+                 NBDKIT_ARG_CAPS, __VA_ARGS__, QEMU_NBDKIT_CAPS_LAST, NBDKIT_ARG_END)
+
+#define DO_TEST_NOCAPS(_name) \
+    DO_TEST_FULL(_name, NBDKIT_ARG_END)
+
+    DO_TEST("disk-cdrom-network", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
+    DO_TEST("disk-network-http", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
+    DO_TEST("disk-network-source-curl-nbdkit-backing", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
+    DO_TEST("disk-network-source-curl", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
+    DO_TEST("disk-network-ssh", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
+
+    qemuTestDriverFree(&driver);
+
+    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIR_TEST_MAIN(mymain)
-- 
2.39.1



More information about the libvir-list mailing list