summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <freddy77@gmail.com>2023-11-13 17:24:52 +0000
committerFrediano Ziglio <fziglio@redhat.com>2023-11-22 07:36:40 +0000
commitfe1c25f530b95d32cc81bc1a395d80ace631d2dd (patch)
tree0d97e12ce4b48b581e99097c66b115b50aaa21df
parent7cfebdf61b59147f23421b05c979ebb671feac10 (diff)
test-listen: Use OpenSSL BIO instead of GIO libraryHEADmaster
test-listen using GIO had issues running under CI for a while. GIO is reading some desktop configuration so it's not very CI friendly. So instead of using GIO use OpenSSL BIO. The code does not get much bigger or complicated. We are already using OpenSSL so we are not adding dependencies. This fixes CI for Fedora 39 (just released and available on docker). This allowed to remove an old workaround for GIO in .gitlab-ci.yml (cfr commit 89edf80821acaaf1a9287fdb682faa12e680de4f "ci: Workaround an issue with GLib on Fedora 30") Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
-rw-r--r--.gitlab-ci.yml8
-rw-r--r--server/tests/Makefile.am2
-rw-r--r--server/tests/meson.build5
-rw-r--r--server/tests/test-listen.c139
4 files changed, 63 insertions, 91 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b02a2aeb..ee49506c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,19 +8,13 @@ before_script:
glib2-devel pixman-devel alsa-lib-devel openssl-devel libjpeg-turbo-devel
libcacard-devel cyrus-sasl-devel lz4-devel opus-devel
gstreamer1-devel gstreamer1-plugins-base-devel
- dconf gcc-c++ autoconf-archive
+ gcc-c++ autoconf-archive
-y
- &protocol >
git clone --depth=1 ${CI_REPOSITORY_URL/spice.git/spice-protocol.git} &&
meson setup --buildtype=release spice-protocol build-spice-protocol --prefix=/usr --werror &&
ninja -C build-spice-protocol install &&
rm -rf build-spice-protocol
- # This is a workaround for Fedora docker image, this will add some
- # missing configuration
- # '/org/gnome/system/location/enabled' is just the first key path
- # I found, nothing special in it
- # TODO remove when the image will fix this issue
- - dconf reset /org/gnome/system/location/enabled || true
makecheck:
script:
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index 5a7bd52e..e9231fc9 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -18,7 +18,6 @@ AM_CPPFLAGS = \
-I$(top_builddir)/server \
-I$(top_srcdir)/server/tests \
$(SPICE_COMMON_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
$(GLIB2_CFLAGS) \
$(SMARTCARD_CFLAGS) \
$(SPICE_NONPKGCONFIG_CFLAGS) \
@@ -50,7 +49,6 @@ LDADD = \
libtest.a \
$(SPICE_COMMON_DIR)/common/libspice-common.la \
$(top_builddir)/server/libserver.la \
- $(GIO_UNIX_LIBS) \
$(GLIB2_LIBS) \
$(SPICE_NONPKGCONFIG_LIBS) \
$(NULL)
diff --git a/server/tests/meson.build b/server/tests/meson.build
index 3e0606cd..6af904d6 100644
--- a/server/tests/meson.build
+++ b/server/tests/meson.build
@@ -1,8 +1,5 @@
test_lib_include = [spice_server_include, include_directories('.')]
-test_lib_deps = [spice_server_deps, spice_common.get_variable('gio2_deps')]
-if host_machine.system() != 'windows'
- test_lib_deps += [dependency('gio-unix-2.0')]
-endif
+test_lib_deps = spice_server_deps
test_lib_sources = [
'basic-event-loop.c',
diff --git a/server/tests/test-listen.c b/server/tests/test-listen.c
index 4d4bd159..f3bdccd6 100644
--- a/server/tests/test-listen.c
+++ b/server/tests/test-listen.c
@@ -26,11 +26,16 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
-#include <gio/gio.h>
+
#ifndef _WIN32
-#include <gio/gunixsocketaddress.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#endif
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+
#include "test-glib-compat.h"
/* Arbitrary base port, we want a port which is not in use by the system, and
@@ -40,11 +45,6 @@
#define PKI_DIR SPICE_TOP_SRCDIR "/server/tests/pki/"
-static bool error_is_set(GError **error)
-{
- return ((error != NULL) && (*error != NULL));
-}
-
typedef struct {
SpiceCoreInterface *core;
SpiceTimer *exit_mainloop_timer;
@@ -93,91 +93,82 @@ static void test_event_loop_run(TestEventLoop *event_loop)
basic_event_loop_mainloop();
}
-static GIOStream *fake_client_connect(GSocketConnectable *connectable, GError **error)
+static BIO *fake_client_connect(const char *hostname, int port, bool use_tls)
{
- GSocketClient *client;
- GSocketConnection *connection;
+ if (port < 0) {
+#ifndef _WIN32
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, hostname);
+ if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(sock);
+ return NULL;
+ }
+ return BIO_new_fd(sock, 0);
+#else
+ g_assert_not_reached();
+#endif
+ }
- client = g_socket_client_new();
- connection = g_socket_client_connect(client, connectable, NULL, error);
+ char con_buf[256];
+ g_snprintf(con_buf, sizeof(con_buf), "%s:%d", hostname, port);
- g_object_unref(client);
+ SSL_CTX *ctx = NULL;
+ BIO *bio;
+ if (use_tls) {
+ ctx = SSL_CTX_new(TLS_client_method());
+ g_assert_nonnull(ctx);
- return G_IO_STREAM(connection);
-}
+ bio = BIO_new_ssl_connect(ctx);
+ g_assert_nonnull(bio);
-static GIOStream *fake_client_connect_tls(GSocketConnectable *connectable, GError **error)
-{
- GSocketClient *client;
- GSocketConnection *connection;
- GIOStream *tls_connection;
-
- client = g_socket_client_new();
- connection = g_socket_client_connect(client, connectable, NULL, error);
- g_assert_no_error(*error);
- tls_connection = g_tls_client_connection_new(G_IO_STREAM(connection),
- connectable,
- error);
- g_assert_no_error(*error);
- /* Disable all certificate checks as our test setup is known to be invalid */
- g_tls_client_connection_set_validation_flags(G_TLS_CLIENT_CONNECTION(tls_connection), (GTlsCertificateFlags) 0);
-
- g_object_unref(connection);
- g_object_unref(client);
-
- return tls_connection;
+ BIO_set_conn_hostname(bio, con_buf);
+ } else {
+ bio = BIO_new_connect(con_buf);
+ g_assert_nonnull(bio);
+ }
+
+ if (BIO_do_connect(bio) <= 0) {
+ BIO_free(bio);
+ bio = NULL;
+ }
+
+ SSL_CTX_free(ctx);
+ return bio;
}
-static void check_magic(GIOStream *io_stream, GError **error)
+static void check_magic(BIO *bio)
{
uint8_t buffer[4];
- gsize bytes_read;
- gsize bytes_written;
- GInputStream *input_stream;
- GOutputStream *output_stream;
/* send dummy data to trigger a response from the server */
- output_stream = g_io_stream_get_output_stream(io_stream);
memset(buffer, 0xa5, G_N_ELEMENTS(buffer));
- g_output_stream_write_all(output_stream, buffer, G_N_ELEMENTS(buffer), &bytes_written, NULL, error);
- if (error_is_set(error)) {
- return;
- }
+ g_assert_cmpint(BIO_write(bio, buffer, G_N_ELEMENTS(buffer)), ==, G_N_ELEMENTS(buffer));
- input_stream = g_io_stream_get_input_stream(io_stream);
- g_input_stream_read_all(input_stream, buffer, G_N_ELEMENTS(buffer), &bytes_read, NULL, error);
- if (error_is_set(error)) {
- return;
- }
- g_assert_cmpuint(bytes_read, ==, G_N_ELEMENTS(buffer));
+ g_assert_cmpint(BIO_read(bio, buffer, G_N_ELEMENTS(buffer)), ==, G_N_ELEMENTS(buffer));
g_assert_cmpint(memcmp(buffer, "REDQ", 4), ==, 0);
}
typedef struct
{
- GSocketConnectable *connectable;
+ const char *hostname;
+ int port;
bool use_tls;
TestEventLoop *event_loop;
} ThreadData;
static gpointer check_magic_thread(gpointer data)
{
- GError *error = NULL;
ThreadData *thread_data = (ThreadData*) data;
- GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(thread_data->connectable);
- GIOStream *stream;
+ BIO *bio;
- if (thread_data->use_tls) {
- stream = fake_client_connect_tls(connectable, &error);
- } else {
- stream = fake_client_connect(connectable, &error);
- }
- g_assert_no_error(error);
- check_magic(stream, &error);
- g_assert_no_error(error);
+ bio = fake_client_connect(thread_data->hostname, thread_data->port, thread_data->use_tls);
+ g_assert_nonnull(bio);
+ check_magic(bio);
- g_object_unref(stream);
- g_object_unref(connectable);
+ BIO_free_all(bio);
test_event_loop_quit(thread_data->event_loop);
g_free(thread_data);
@@ -187,17 +178,10 @@ static gpointer check_magic_thread(gpointer data)
static gpointer check_no_connect_thread(gpointer data)
{
- GError *error = NULL;
ThreadData *thread_data = (ThreadData*) data;
- GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(thread_data->connectable);
- GIOStream *stream;
- stream = fake_client_connect(connectable, &error);
- g_assert_nonnull(error);
- g_assert_null(stream);
- g_clear_error(&error);
-
- g_object_unref(connectable);
+ BIO *bio = fake_client_connect(thread_data->hostname, thread_data->port, false);
+ g_assert_null(bio);
test_event_loop_quit(thread_data->event_loop);
g_free(thread_data);
@@ -213,16 +197,15 @@ static GThread *fake_client_new(GThreadFunc thread_func,
ThreadData *thread_data = g_new0(ThreadData, 1);
if (port == -1) {
-#ifndef _WIN32
- thread_data->connectable = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(hostname));
-#else
+#ifdef _WIN32
g_assert_not_reached();
#endif
} else {
g_assert_cmpuint(port, >, 0);
g_assert_cmpuint(port, <, 65536);
- thread_data->connectable = g_network_address_new(hostname, port);
}
+ thread_data->hostname = hostname;
+ thread_data->port = port;
thread_data->use_tls = use_tls;
thread_data->event_loop = event_loop;