diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3a9ca76493bc5fed174d1f9fb4ee7a26cdd0250b..cb72cdf13973df92943324be4ab1037bdfa8a387 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -261,6 +261,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest \
qemumonitortest qemumonitorjsontest qemuhotplugtest \
qemuagenttest qemucapabilitiestest qemucaps2xmltest \
qemucommandutiltest
+test_helpers += qemucapsprobe
endif WITH_QEMU
if WITH_LXC
@@ -426,6 +427,7 @@ test_libraries += libqemumonitortestutils.la \
libqemutestdriver.la \
qemuxml2argvmock.la \
qemucaps2xmlmock.la \
+ qemucapsprobemock.la \
$(NULL)
endif WITH_QEMU
@@ -603,6 +605,17 @@ qemucapabilitiestest_SOURCES = \
qemucapabilitiestest_LDADD = libqemumonitortestutils.la \
$(qemu_LDADDS) $(LDADDS)
+qemucapsprobe_SOURCES = \
+ qemucapsprobe.c
+qemucapsprobe_LDADD = \
+ libqemutestdriver.la $(LDADDS)
+
+qemucapsprobemock_la_SOURCES = \
+ qemucapsprobemock.c
+qemucapsprobemock_la_CFLAGS = $(AM_CFLAGS)
+qemucapsprobemock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
+qemucapsprobemock_la_LIBADD = $(MOCKLIBS_LIBS)
+
qemucommandutiltest_SOURCES = \
qemucommandutiltest.c \
testutils.c testutils.h \
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index ccf0b7227518442c8b2cf76f2620c90e32f4c8d4..ac9f7a88db3a66934383bcf93ad661d3b1132d85 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -194,6 +194,11 @@ mymain(void)
DO_TEST("caps_2.5.0-1");
DO_TEST("caps_2.6.0-1");
+ /*
+ * Run "tests/qemucapsprobe /path/to/qemu/binary >foo.replies"
+ * to generate updated or new *.replies data files.
+ */
+
qemuTestDriverFree(&driver);
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
new file mode 100644
index 0000000000000000000000000000000000000000..9557055074d712cca686042f94d02d112328b22e
--- /dev/null
+++ b/tests/qemucapsprobe.c
@@ -0,0 +1,82 @@
+/*
+ * 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
+ * .
+ *
+ * Author: Jiri Denemark
+ */
+
+#include
+
+#include "testutils.h"
+#include "internal.h"
+#include "virthread.h"
+#include "qemu/qemu_capabilities.h"
+#define __QEMU_CAPSRIV_H_ALLOW__ 1
+#include "qemu/qemu_capspriv.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+
+static void
+eventLoop(void *opaque ATTRIBUTE_UNUSED)
+{
+ while (1) {
+ if (virEventRunDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ fprintf(stderr, "Failed to run event loop: %s\n",
+ err && err->message ? err->message : "Unknown error");
+ }
+ }
+}
+
+
+int
+main(int argc, char **argv)
+{
+ virThread thread;
+ virQEMUCapsPtr caps;
+
+ VIRT_TEST_PRELOAD(abs_builddir "/.libs/qemucapsprobemock.so");
+
+ if (argc != 2) {
+ fprintf(stderr, "%s QEMU_binary\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (virThreadInitialize() < 0 ||
+ virInitialize() < 0) {
+ fprintf(stderr, "Failed to initialize libvirt");
+ return EXIT_FAILURE;
+ }
+
+ if (virEventRegisterDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ fprintf(stderr, "Failed to register event implementation: %s\n",
+ err && err->message ? err->message: "Unknown error");
+ return EXIT_FAILURE;
+ }
+
+ if (virThreadCreate(&thread, false, eventLoop, NULL) < 0)
+ return EXIT_FAILURE;
+
+ if (!(caps = virQEMUCapsNewForBinaryInternal(argv[1], "/tmp", NULL,
+ -1, -1, true)))
+ return EXIT_FAILURE;
+
+ virObjectUnref(caps);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/qemucapsprobemock.c b/tests/qemucapsprobemock.c
new file mode 100644
index 0000000000000000000000000000000000000000..8ff4de970b0488dda3aac2e6c13d0e50afe00fbc
--- /dev/null
+++ b/tests/qemucapsprobemock.c
@@ -0,0 +1,93 @@
+/*
+ * 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
+ * .
+ *
+ * Author: Jiri Denemark
+ */
+
+#include
+#include
+#include
+
+#include "internal.h"
+#include "viralloc.h"
+#include "virjson.h"
+#include "qemu/qemu_monitor.h"
+#include "qemu/qemu_monitor_json.h"
+
+#define REAL_SYM(realFunc) \
+ do { \
+ if (!realFunc && !(realFunc = dlsym(RTLD_NEXT, __FUNCTION__))) { \
+ fprintf(stderr, "Cannot find real '%s' symbol\n", \
+ __FUNCTION__); \
+ abort(); \
+ } \
+ } while (0)
+
+
+static int (*realQemuMonitorSend)(qemuMonitorPtr mon,
+ qemuMonitorMessagePtr msg);
+
+int
+qemuMonitorSend(qemuMonitorPtr mon,
+ qemuMonitorMessagePtr msg)
+{
+ REAL_SYM(realQemuMonitorSend);
+
+ fprintf(stderr, "%s", msg->txBuffer);
+
+ return realQemuMonitorSend(mon, msg);
+}
+
+
+static int (*realQemuMonitorJSONIOProcessLine)(qemuMonitorPtr mon,
+ const char *line,
+ qemuMonitorMessagePtr msg);
+
+int
+qemuMonitorJSONIOProcessLine(qemuMonitorPtr mon,
+ const char *line,
+ qemuMonitorMessagePtr msg)
+{
+ virJSONValuePtr value = NULL;
+ char *json = NULL;
+ int ret;
+
+ REAL_SYM(realQemuMonitorJSONIOProcessLine);
+
+ ret = realQemuMonitorJSONIOProcessLine(mon, line, msg);
+
+ if (ret == 0 &&
+ (value = virJSONValueFromString(line)) &&
+ (json = virJSONValueToString(value, 1))) {
+ char *p;
+ bool skip = false;
+
+ for (p = json; *p; p++) {
+ if (skip && *p == '\n') {
+ continue;
+ } else {
+ skip = *p == '\n';
+ putchar(*p);
+ }
+ }
+ putchar('\n');
+ }
+
+ VIR_FREE(json);
+ virJSONValueFree(value);
+ return ret;
+}