From 79e1fc63adbd3eac7788d8c8b034ec08f7e0dcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 27 Jan 2023 21:55:57 +0100 Subject: [PATCH] tests: Add service door Wayland test case Checks that the MetaWaylandClient from the service door is the one owning the client connection opened via the D-Bus interface. Part-of: --- src/tests/meson.build | 8 ++ src/tests/service-channel-tests.c | 117 ++++++++++++++++++ src/tests/wayland-test-clients/meson.build | 22 +++- .../wayland-test-clients/service-client.c | 98 +++++++++++++++ 4 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 src/tests/service-channel-tests.c create mode 100644 src/tests/wayland-test-clients/service-client.c diff --git a/src/tests/meson.build b/src/tests/meson.build index 79f7a7e91..7c20422dd 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -429,6 +429,14 @@ if have_native_tests 'wayland-client-tests.c', ], }, + { + 'name': 'service-channel', + 'suite': 'wayland', + 'sources': [ + 'service-channel-tests.c', + wayland_test_utils, + ], + }, ] if have_xwayland test_cases += [ diff --git a/src/tests/service-channel-tests.c b/src/tests/service-channel-tests.c new file mode 100644 index 000000000..1a608d959 --- /dev/null +++ b/src/tests/service-channel-tests.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2023 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "core/meta-service-channel.h" +#include "core/window-private.h" +#include "meta-test/meta-context-test.h" +#include "tests/meta-test-utils.h" +#include "tests/meta-wayland-test-driver.h" +#include "tests/meta-wayland-test-utils.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-wayland-client-private.h" +#include "wayland/meta-wayland-surface.h" + +static MetaContext *test_context; +static MetaWaylandTestDriver *test_driver; +static MetaVirtualMonitor *virtual_monitor; + +static void +meta_test_service_channel_wayland (void) +{ + MetaServiceChannel *service_channel = meta_context_get_service_channel (test_context); + MetaWaylandTestClient *wayland_test_client; + MetaWindow *window; + MetaWaylandSurface *surface; + struct wl_resource *surface_resource; + struct wl_client *wl_client; + MetaWaylandClient *wayland_client; + + wayland_test_client = + meta_wayland_test_client_new (test_context, "service-client"); + + window = meta_wait_for_client_window (test_context, "test service client"); + surface = meta_window_get_wayland_surface (window); + g_assert_nonnull (surface); + + surface_resource = meta_wayland_surface_get_resource (surface); + wl_client = wl_resource_get_client (surface_resource); + + wayland_client = + meta_service_channel_get_service_client (service_channel, + META_SERVICE_CLIENT_TYPE_PORTAL_BACKEND); + g_assert_nonnull (wayland_client); + g_assert_true (meta_wayland_client_matches (wayland_client, wl_client)); + + meta_wayland_test_driver_emit_sync_event (test_driver, 1); + meta_wayland_test_client_finish (wayland_test_client); +} + +static void +on_before_tests (void) +{ + MetaWaylandCompositor *compositor = + meta_context_get_wayland_compositor (test_context); + + test_driver = meta_wayland_test_driver_new (compositor); + virtual_monitor = meta_create_test_monitor (test_context, + 400, 400, 60.0); +} + +static void +on_after_tests (void) +{ + g_clear_object (&test_driver); + g_clear_object (&virtual_monitor); +} + +static void +init_tests (void) +{ + g_test_add_func ("/service-channel/wayland", + meta_test_service_channel_wayland); +} + +int +main (int argc, + char **argv) +{ + g_autoptr (MetaContext) context = NULL; + g_autoptr (GError) error = NULL; + + context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS, + META_CONTEXT_TEST_FLAG_NO_X11); + g_assert (meta_context_configure (context, &argc, &argv, NULL)); + + test_context = context; + + init_tests (); + + g_signal_connect (context, "before-tests", + G_CALLBACK (on_before_tests), NULL); + g_signal_connect (context, "after-tests", + G_CALLBACK (on_after_tests), NULL); + + return meta_context_test_run_tests (META_CONTEXT_TEST (context), + META_TEST_RUN_FLAG_CAN_SKIP); + + return EXIT_SUCCESS; +} diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build index a0d548346..959ad8998 100644 --- a/src/tests/wayland-test-clients/meson.build +++ b/src/tests/wayland-test-clients/meson.build @@ -57,6 +57,15 @@ wayland_test_clients = [ libgbm_dep, ], }, + { + 'name': 'service-client', + 'extra_sources': [ + built_dbus_sources['meta-dbus-service-channel'], + ], + 'extra_deps': [ + gio_unix_dep, + ], + }, ] foreach test : wayland_test_clients @@ -70,11 +79,16 @@ foreach test : wayland_test_clients deps += test['extra_deps'] endif + test_client_sources = [ + '@0@.c'.format(test_name), + common_sources, + ] + if test.has_key('extra_sources') + test_client_sources += test['extra_sources'] + endif + executable(test_name, - sources: [ - '@0@.c'.format(test_name), - common_sources, - ], + sources: test_client_sources, include_directories: tests_includes, c_args: tests_c_args, dependencies: deps, diff --git a/src/tests/wayland-test-clients/service-client.c b/src/tests/wayland-test-clients/service-client.c new file mode 100644 index 000000000..7bf02eade --- /dev/null +++ b/src/tests/wayland-test-clients/service-client.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2023 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "tests/wayland-test-clients/wayland-test-client-utils.h" + +#include "meta-dbus-service-channel.h" + +typedef enum _ServiceClientType +{ + SERVICE_CLIENT_TYPE_NONE, + SERVICE_CLIENT_TYPE_PORTAL_BACKEND, +} ServiceClientType; + +static WaylandDisplay *display; +static WaylandSurface *surface; + +static void +on_sync_event (WaylandDisplay *display, + uint32_t serial, + uint32_t *last_sync_event) +{ + *last_sync_event = serial; +} + +int +main (int argc, + char **argv) +{ + g_autoptr (GError) error = NULL; + g_autoptr (MetaDBusServiceChannel) service_channel = NULL; + g_autoptr (GVariant) fd_variant = NULL; + g_autoptr (GUnixFDList) fd_list = NULL; + int fd; + struct wl_display *wayland_display; + uint32_t last_sync_event = UINT32_MAX; + + service_channel = + meta_dbus_service_channel_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.Mutter.ServiceChannel", + "/org/gnome/Mutter/ServiceChannel", + NULL, + &error); + g_assert_nonnull (service_channel); + + if (!meta_dbus_service_channel_call_open_wayland_service_connection_sync ( + service_channel, + SERVICE_CLIENT_TYPE_PORTAL_BACKEND, + NULL, + &fd_variant, + &fd_list, + NULL, &error)) + g_error ("Failed to open Wayland service connection: %s", error->message); + + fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), &error); + g_assert_cmpint (fd, >=, 0); + + wayland_display = wl_display_connect_to_fd (fd); + + display = wayland_display_new_full (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER, + wayland_display); + g_signal_connect (display, "sync-event", + G_CALLBACK (on_sync_event), &last_sync_event); + + surface = wayland_surface_new (display, "test service client", + 100, 100, 0xffabcdff); + wl_surface_commit (surface->wl_surface); + + while (last_sync_event != 1) + { + if (wl_display_dispatch (display->display) == -1) + return EXIT_FAILURE; + } + + wayland_surface_free (surface); + g_object_unref (display); +}