Signed-off-by: Laurent Vivier
Acked-by: Michael S. Tsirkin
Acked-by: Thomas Huth
---
Notes:
v7:
- disable test_dgram_mcast() on windows
- disable test_dgram_unix() on windows as it also fails
(we test for unix support dynamically but the test is done with
SOCK_STREAM, and it fails here with SOCK_DGRAM)
- Tested with cirrus-ci (Thank you Thomas)
v6:
- call socket_init() otherwise socket_check_protocol_support() fails
- if socket_check_protocol_support() fails then calls g_abort() to
report a problem.
v5:
- disable test_stream_fd and test_dgram_fd on windows as socketpair()
is not defined.
- enable test_stream_unix_abstract only on linux as "abstract"
unix socket parameter is only defined on linux.
v4:
- rework EXPECT_STATE()
- use g_dir_make_tmp()
v3:
- Add "-M none" to avoid error:
"No machine specified, and there is no default"
v2:
- Fix ipv6 free port allocation
- Check for IPv4, IPv6, AF_UNIX
- Use g_mkdtemp() rather than g_file_open_tmp()
- Use socketpair() in test_stream_fd()
v1: compared to v14 of "qapi: net: add unix socket type support to netdev
backend":
- use IP addresses 127.0.0.1 and ::1 rather than localhost
tests/qtest/meson.build | 2 +
tests/qtest/netdev-socket.c | 448
2 files changed, 450 insertions(+)
create mode 100644 tests/qtest/netdev-socket.c
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f0ebb5fac603..d752304711e2 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -21,6 +21,7 @@ qtests_generic = [
'test-hmp',
'qos-test',
'readconfig-test',
+ 'netdev-socket',
]
if config_host.has_key('CONFIG_MODULES')
qtests_generic += [ 'modules-test' ]
@@ -298,6 +299,7 @@ qtests = {
'tpm-tis-device-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
+ 'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
}
gvnc = dependency('gvnc-1.0', required: false)
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
new file mode 100644
index ..6ba256e1730d
--- /dev/null
+++ b/tests/qtest/netdev-socket.c
@@ -0,0 +1,448 @@
+/*
+ * QTest testcase for netdev stream and dgram
+ *
+ * Copyright (c) 2022 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/sockets.h"
+#include
+#include "../unit/socket-helpers.h"
+#include "libqtest.h"
+
+#define CONNECTION_TIMEOUT5
+
+#define EXPECT_STATE(q, e, t) \
+do { \
+char *resp = NULL;\
+g_test_timer_start(); \
+do { \
+g_free(resp); \
+resp = qtest_hmp(q, "info network"); \
+if (t) { \
+strrchr(resp, t)[0] = 0; \
+} \
+if (g_str_equal(resp, e)) { \
+break;\
+} \
+} while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
+g_assert_cmpstr(resp, ==, e); \
+g_free(resp); \
+} while (0)
+
+static gchar *tmpdir;
+
+static int inet_get_free_port_socket_ipv4(int sock)
+{
+struct sockaddr_in addr;
+socklen_t len;
+
+memset(, 0, sizeof(addr));
+addr.sin_family = AF_INET;
+addr.sin_addr.s_addr = INADDR_ANY;
+addr.sin_port = 0;
+if (bind(sock, (struct sockaddr *), sizeof(addr)) < 0) {
+return -1;
+}
+
+len = sizeof(addr);
+if (getsockname(sock, (struct sockaddr *), ) < 0) {
+return -1;
+}
+
+return ntohs(addr.sin_port);
+}
+
+static int inet_get_free_port_socket_ipv6(int sock)
+{
+struct sockaddr_in6 addr;
+socklen_t len;
+
+memset(, 0, sizeof(addr));
+addr.sin6_family = AF_INET6;
+addr.sin6_addr = in6addr_any;
+addr.sin6_port = 0;
+if (bind(sock, (struct sockaddr *), sizeof(addr)) < 0) {
+return -1;
+}
+
+len = sizeof(addr);
+if (getsockname(sock, (struct sockaddr *), ) < 0) {
+return -1;
+}
+
+return ntohs(addr.sin6_port);
+}
+
+static int inet_get_free_port_multiple(int nb, int *port, bool ipv6)
+{
+int sock[nb];
+int i;
+
+for (i = 0; i < nb; i++) {
+sock[i] = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
+if (sock[i] < 0) {
+break;
+}
+port[i] = ipv6 ?