Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tests/Makefile.am | 10 ++-
tests/iohelpermessagetest.c | 177 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 186 insertions(+), 1 deletion(-)
create mode 100644 tests/iohelpermessagetest.c
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 444e0fd..a87de5f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -379,7 +379,8 @@ test_scripts += $(libvirtd_test_scripts)
test_programs += \
eventtest \
- libvirtdconftest
+ libvirtdconftest \
+ iohelpermessagetest
else ! WITH_LIBVIRTD
EXTRA_DIST += $(libvirtd_test_scripts)
endif ! WITH_LIBVIRTD
@@ -1296,6 +1297,13 @@ if WITH_LIBVIRTD
eventtest_SOURCES = \
eventtest.c testutils.h testutils.c
eventtest_LDADD = -lrt $(LDADDS)
+
+iohelpermessagetest_SOURCES = \
+ iohelpermessagetest.c testutils.h testutils.c
+iohelpermessagetest_CFLAGS = \
+ $(AM_CFLAGS) -I$(top_srcdir)/src/iohelper
+iohelpermessagetest_LDADD = \
+ $(LDADDS) ../src/libvirt-iohelper.la
endif WITH_LIBVIRTD
libshunload_la_SOURCES = shunloadhelper.c
diff --git a/tests/iohelpermessagetest.c b/tests/iohelpermessagetest.c
new file mode 100644
index 0000000..293c107
--- /dev/null
+++ b/tests/iohelpermessagetest.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2016 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(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "testutils.h"
+#include "internal.h"
+#include "iohelper_message.h"
+#include "virlog.h"
+
+VIR_LOG_INIT("tests.iohelpermessagetest");
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+typedef struct {
+ const char * const *msg;
+ unsigned int *len;
+} testData;
+
+typedef testData *testDataPtr;
+
+static int
+testInit(iohelperCtlPtr ctl[2], int fd[2], bool blockR, bool blockW)
+{
+ ctl[0] = ctl[1] = NULL;
+
+ if (pipe(fd) < 0) {
+ fprintf(stderr, "Cannot create pipe: %d", errno);
+ return -1;
+ }
+
+ if (virSetBlocking(fd[0], blockR) < 0 ||
+ virSetBlocking(fd[1], blockW) < 0)
+ goto error;
+
+ if (!(ctl[0] = iohelperCtlNew(fd[0], blockR)) ||
+ !(ctl[1] = iohelperCtlNew(fd[1], blockW)))
+ goto error;
+
+ return 0;
+ error:
+ virObjectUnref(ctl[0]);
+ virObjectUnref(ctl[1]);
+ ctl[0] = ctl[1] = NULL;
+ return -1;
+}
+
+static int
+testBlocking(const void *opaque)
+{
+ int ret = -1;
+ const testData *data = opaque;
+ iohelperCtlPtr ioCtl[2];
+ int pipeFD[2] = {-1, -1};
+ size_t idx = 0;
+ bool quit = !data->msg && !data->len;
+ char *genMsg = NULL;
+ char buf[1024];
+
+ if (testInit(ioCtl, pipeFD, true, true) < 0)
+ goto cleanup;
+
+ while (!quit) {
+ const char *msg = NULL;
+ size_t len = 0;
+ ssize_t nread = 0, nwritten = 0;
+ size_t i;
+
+ if (data->len) {
+ len = data->len[idx];
+ quit = !data->len[idx + 1];
+ VIR_FREE(genMsg);
+ if (VIR_ALLOC_N(genMsg, len) < 0)
+ goto cleanup;
+ for (i = 0; i < len; i++)
+ genMsg[i] = i;
+ msg = genMsg;
+ VIR_DEBUG("Testing string of len %zu", len);
+ } else {
+ msg = data->msg[idx];
+ quit = !data->msg[idx + 1];
+ len = strlen(msg);
+ VIR_DEBUG("Testing string '%s'", msg);
+ }
+
+ if ((nwritten = iohelperWrite(ioCtl[1], msg, len)) < 0) {
+ virFilePrintf(stderr, "Unable to write message (errno=%d)\n",
errno);
+ goto cleanup;
+ }
+
+ if (nwritten != len) {
+ virFilePrintf(stderr, "Mismatched data len written=%zu
wanted=%zu\n", nwritten, len);
+ goto cleanup;
+ }
+
+ if ((nread = iohelperRead(ioCtl[0], buf, sizeof(buf))) < 0) {
+ virFilePrintf(stderr, "Unable to read message (errno=%d)\n",
errno);
+ goto cleanup;
+ }
+
+ if (nread != nwritten) {
+ virFilePrintf(stderr, "Mismatched data len written=%zu read=%zu\n",
nwritten, nread);
+ goto cleanup;
+ }
+
+ buf[nread] = '\0';
+
+ if (memcmp(buf, msg, nread)) {
+ virFilePrintf(stderr, "Mismatched data written='%s'
read='%s'\n", msg, buf);
+ goto cleanup;
+ }
+
+ idx++;
+ }
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(genMsg);
+ virObjectUnref(ioCtl[0]);
+ virObjectUnref(ioCtl[1]);
+ VIR_FORCE_CLOSE(pipeFD[0]);
+ VIR_FORCE_CLOSE(pipeFD[1]);
+ return ret;
+}
+
+static int
+mymain(void)
+{
+ int ret = 0;
+
+#define DO_TEST_BLOCKING_SIMPLE(...) \
+ do { \
+ const char *msg[] = { __VA_ARGS__, NULL}; \
+ testData data = {.msg = msg, .len = NULL }; \
+ if (virTestRun("Blocking simple", testBlocking, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
+#define DO_TEST_BLOCKING_LEN(...) \
+ do { \
+ unsigned int len[] = { __VA_ARGS__, 0}; \
+ testData data = {.msg = NULL, .len = len }; \
+ if (virTestRun("Blocking len", testBlocking, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
+ DO_TEST_BLOCKING_SIMPLE("Hello world");
+ DO_TEST_BLOCKING_SIMPLE("Hello world", "Hello",
"world");
+
+ DO_TEST_BLOCKING_LEN(10);
+ DO_TEST_BLOCKING_LEN(1024);
+ DO_TEST_BLOCKING_LEN(32, 64, 128, 512, 1024);
+
+ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN(mymain)
--
2.8.4