From ee5716798aaa858747fcb8bbd47189ddbede5274 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Thu, 9 Dec 2021 13:35:54 +0200 Subject: [PATCH] tests/safe-signal-output-removal: Add test for output removal This simulates an output removal which should trigger a crash when the compositor is shutdown abruptly by having a view with a listener installed on its output_destroy signal. This patch assumes that weston_compositor_remove_output() has already been amended to use the more safer version for triggering signal emission. As both shells use this construct it should catch any potential signal corruption. Signed-off-by: Marius Vlad --- tests/meson.build | 7 ++ tests/safe-signal-output-removal-test.c | 133 ++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 tests/safe-signal-output-removal-test.c diff --git a/tests/meson.build b/tests/meson.build index c642ec00..d8e96e77 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -217,6 +217,13 @@ tests = [ ], }, { 'name': 'safe-signal', }, + { 'name': 'safe-signal-output-removal', + 'sources': [ + 'safe-signal-output-removal-test.c', + '../shared/shell-utils.c', + ], + 'dep_objs': [ dep_lib_desktop ] + }, ] tests_standalone = [ diff --git a/tests/safe-signal-output-removal-test.c b/tests/safe-signal-output-removal-test.c new file mode 100644 index 00000000..0a747307 --- /dev/null +++ b/tests/safe-signal-output-removal-test.c @@ -0,0 +1,133 @@ +/* + * Copyright 2021 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "config.h" + +#include +#include +#include +#include + +#include "../shared/signal.h" +#include "../shared/shell-utils.h" +#include "weston-test-client-helper.h" +#include "weston-test-fixture-compositor.h" + +struct test_output { + struct weston_compositor *compositor; + struct weston_output *output; + struct wl_listener output_destroy_listener; + struct weston_view *view; +}; + +static enum test_result_code +fixture_setup(struct weston_test_harness *harness) +{ + struct compositor_setup setup; + + compositor_setup_defaults(&setup); + setup.shell = SHELL_TEST_DESKTOP; + + return weston_test_harness_execute_as_plugin(harness, &setup); +} + +DECLARE_FIXTURE_SETUP(fixture_setup); + +static void +output_destroy(struct test_output *t_output) +{ + t_output->output = NULL; + t_output->output_destroy_listener.notify = NULL; + + if (t_output->view) + weston_surface_destroy(t_output->view->surface); + + wl_list_remove(&t_output->output_destroy_listener.link); + free(t_output); +} + +static void +notify_output_destroy(struct wl_listener *listener, void *data) +{ + struct test_output *t_output = + container_of(listener, struct test_output, output_destroy_listener); + + output_destroy(t_output); +} + +static void +output_create_view(struct test_output *t_output) +{ + struct weston_solid_color_surface solid_surface = {}; + + solid_surface.r = 0.5; + solid_surface.g = 0.5; + solid_surface.b = 0.5; + + solid_surface.get_label = NULL; + solid_surface.surface_committed = NULL; + solid_surface.surface_private = NULL; + + t_output->view = + create_solid_color_surface(t_output->compositor, + &solid_surface, 0, 0, 320, 240); + weston_view_set_output(t_output->view, t_output->output); + + /* weston_compositor_remove_output() has to be patched with + * weston_signal_emit_mutable() to avoid signal corruption */ + weston_output_destroy(t_output->output); +} + +static void +output_create(struct weston_output *output) +{ + struct test_output *t_output; + + t_output = zalloc(sizeof *t_output); + if (t_output == NULL) + return; + + t_output->output = output; + t_output->compositor = output->compositor; + + t_output->output_destroy_listener.notify = notify_output_destroy; + wl_signal_add(&t_output->output->destroy_signal, + &t_output->output_destroy_listener); + + output_create_view(t_output); +} + +static void +create_outputs(struct weston_compositor *compositor) +{ + struct weston_output *output, *output_next; + + wl_list_for_each_safe(output, output_next, &compositor->output_list, link) + output_create(output); +} + +PLUGIN_TEST(real_usecase_one) +{ + create_outputs(compositor); +}