[PATCH v2 6/7] commandtest: Test virCommandSetSendBuffer() with virCommandDoAsyncIO()

Michal Privoznik mprivozn at redhat.com
Tue Mar 22 16:02:05 UTC 2022


Introduce a test case which ensures that a daemonized process can
work with virCommandSetSendBuffer() when async IO is enabled.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 tests/commanddata/test29.log | 19 ++++++++
 tests/commandtest.c          | 84 ++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+)
 create mode 100644 tests/commanddata/test29.log

diff --git a/tests/commanddata/test29.log b/tests/commanddata/test29.log
new file mode 100644
index 0000000000..49993a4947
--- /dev/null
+++ b/tests/commanddata/test29.log
@@ -0,0 +1,19 @@
+ARG:--close-stdin
+ARG:--readfd
+ARG:3
+ENV:DISPLAY=:0.0
+ENV:HOME=/home/test
+ENV:HOSTNAME=test
+ENV:LANG=C
+ENV:LOGNAME=test
+ENV:PATH=/usr/bin:/bin
+ENV:TMPDIR=/tmp
+ENV:USER=test
+FD:0
+FD:1
+FD:2
+FD:3
+FD:6
+DAEMON:yes
+CWD:/
+UMASK:0022
diff --git a/tests/commandtest.c b/tests/commandtest.c
index 10a051124d..573a4f250d 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -25,6 +25,7 @@
 #include <sys/stat.h>
 #ifndef WIN32
 # include <sys/wait.h>
+# include <poll.h>
 #endif
 #include <fcntl.h>
 
@@ -1157,6 +1158,88 @@ test28(const void *unused G_GNUC_UNUSED)
 }
 
 
+static int
+test29(const void *unused G_GNUC_UNUSED)
+{
+    g_autoptr(virCommand) cmd = virCommandNew(abs_builddir "/commandhelper");
+    g_autofree char *pidfile = virPidFileBuildPath(abs_builddir, "commandhelper");
+    pid_t pid;
+    int buffd;
+    VIR_AUTOCLOSE outfd = -1;
+    size_t buflen = 1024 * 10;
+    g_autofree unsigned char *buffer = NULL;
+    g_autofree char *outactual = NULL;
+    g_autofree char *outexpect = NULL;
+    size_t i;
+    size_t outactuallen = 0;
+    int ret = -1;
+
+    if (!pidfile)
+        return -1;
+
+    buffer = g_new0(unsigned char, buflen + 1);
+    for (i = 0; i < buflen; i++) {
+        buffer[i] = 'a' + i % ('z' - 'a' + 1);
+    }
+    buffer[buflen] = '\0';
+
+    outexpect = g_strdup_printf("BEGIN STDOUT\n%sEND STDOUT\n", buffer);
+
+    buffd = virCommandSetSendBuffer(cmd, &buffer, buflen);
+
+    virCommandAddArg(cmd, "--close-stdin");
+    virCommandAddArg(cmd, "--readfd");
+    virCommandAddArgFormat(cmd, "%d", buffd);
+
+    virCommandSetOutputFD(cmd, &outfd);
+    virCommandSetPidFile(cmd, pidfile);
+    virCommandDaemonize(cmd);
+    virCommandDoAsyncIO(cmd);
+
+    if (virCommandRun(cmd, NULL) < 0) {
+        fprintf(stderr, "Cannot run child %s\n", virGetLastErrorMessage());
+        goto cleanup;
+    }
+
+    if (virPidFileReadPath(pidfile, &pid) < 0) {
+        fprintf(stderr, "cannot read pidfile: %s\n", pidfile);
+        goto cleanup;
+    }
+
+    while (1) {
+        char buf[1024] = { 0 };
+        int rc = 0;
+
+        rc = read(outfd, buf, sizeof(buf));
+        if (rc < 0) {
+            fprintf(stderr, "cannot read from output pipe: errno=%d\n", errno);
+            goto cleanup;
+        }
+
+        if (rc == 0)
+            break;
+
+        outactual = g_renew(char, outactual, outactuallen + rc + 1);
+        memcpy(outactual + outactuallen, buf, rc);
+        outactuallen += rc;
+        outactual[outactuallen] = '\0';
+    }
+
+    if (STRNEQ_NULLABLE(outactual, outexpect)) {
+        virTestDifference(stderr, outexpect, outactual);
+        goto cleanup;
+    }
+
+    ret = checkoutput("test29");
+
+ cleanup:
+    if (pidfile)
+        unlink(pidfile);
+
+    return ret;
+}
+
+
 static int
 mymain(void)
 {
@@ -1254,6 +1337,7 @@ mymain(void)
     DO_TEST(test26);
     DO_TEST(test27);
     DO_TEST(test28);
+    DO_TEST(test29);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-- 
2.34.1



More information about the libvir-list mailing list