mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
commandtest: Test virCommandSetSendBuffer() with virCommandDoAsyncIO()
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@redhat.com> Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
This commit is contained in:
parent
5c1b5f208a
commit
e97b6f4bc5
20
tests/commanddata/test29.log
Normal file
20
tests/commanddata/test29.log
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
ARG:--close-stdin
|
||||||
|
ARG:--check-daemonize
|
||||||
|
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
|
@ -25,6 +25,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# include <sys/wait.h>
|
# include <sys/wait.h>
|
||||||
|
# include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
@ -1155,6 +1156,101 @@ 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, "--check-daemonize");
|
||||||
|
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 };
|
||||||
|
struct pollfd pfd = {.fd = outfd, .events = POLLIN, .revents = 0};
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = poll(&pfd, 1, 1000);
|
||||||
|
if (rc < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fprintf(stderr, "poll() returned errno = %d\n", errno);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfd.revents & POLLIN) {
|
||||||
|
rc = read(outfd, buf, sizeof(buf));
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "cannot read from output pipe: errno=%d\n", errno);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
outactual = g_renew(char, outactual, outactuallen + rc + 1);
|
||||||
|
memcpy(outactual + outactuallen, buf, rc);
|
||||||
|
outactuallen += rc;
|
||||||
|
outactual[outactuallen] = '\0';
|
||||||
|
} else if (pfd.revents & POLLERR ||
|
||||||
|
pfd.revents & POLLHUP) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRNEQ_NULLABLE(outactual, outexpect)) {
|
||||||
|
virTestDifference(stderr, outexpect, outactual);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = checkoutput("test29");
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (pidfile)
|
||||||
|
unlink(pidfile);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
@ -1252,6 +1348,7 @@ mymain(void)
|
|||||||
DO_TEST(test26);
|
DO_TEST(test26);
|
||||||
DO_TEST(test27);
|
DO_TEST(test27);
|
||||||
DO_TEST(test28);
|
DO_TEST(test28);
|
||||||
|
DO_TEST(test29);
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user