mutter/src/tests/meta-context-test.c
Sebastian Wick 08c9a775e7 tests: Make sure XDG_CURRENT_DESKTOP is unset
GSettings overrides can be active and set the default value depending on
the XDG_CURRENT_DESKTOP environement variable. For the tests we run, we
rely on the default settings by using the GSettings memory backend but
we also need to make sure not overrides are in place.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3730>
2024-05-21 12:16:06 +00:00

415 lines
12 KiB
C

/*
* Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "meta-test/meta-context-test.h"
#include <glib.h>
#include <gio/gio.h>
#define G_SETTINGS_ENABLE_BACKEND
#include <gio/gsettingsbackend.h>
#include "core/meta-context-private.h"
#include "tests/meta-backend-test.h"
#include "tests/meta-test-shell.h"
#include "tests/meta-test-utils-private.h"
#include "wayland/meta-wayland.h"
#include "wayland/meta-xwayland.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#endif
enum
{
BEFORE_TESTS,
RUN_TESTS,
AFTER_TESTS,
N_SIGNALS
};
static guint signals[N_SIGNALS];
typedef struct _MetaContextTestPrivate
{
MetaContextTestType type;
MetaContextTestFlag flags;
} MetaContextTestPrivate;
struct _MetaContextTestClass
{
MetaContextClass parent_class;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaContextTest, meta_context_test,
META_TYPE_CONTEXT)
static void
ensure_gsettings_memory_backend (void)
{
g_autoptr (GSettingsBackend) memory_backend = NULL;
GSettingsBackend *default_backend;
g_assert_cmpstr (getenv ("GSETTINGS_BACKEND"), ==, "memory");
g_assert_cmpstr (getenv ("XDG_CURRENT_DESKTOP"), ==, "");
memory_backend = g_memory_settings_backend_new ();
default_backend = g_settings_backend_get_default ();
g_assert_true (G_TYPE_FROM_INSTANCE (memory_backend) ==
G_TYPE_FROM_INSTANCE (default_backend));
}
static gboolean
meta_context_test_configure (MetaContext *context,
int *argc,
char ***argv,
GError **error)
{
MetaContextTest *context_test = META_CONTEXT_TEST (context);
MetaContextTestPrivate *priv =
meta_context_test_get_instance_private (context_test);
MetaContextClass *context_class =
META_CONTEXT_CLASS (meta_context_test_parent_class);
g_test_init (argc, argv, NULL);
if (!context_class->configure (context, argc, argv, error))
return FALSE;
g_test_bug_base ("https://gitlab.gnome.org/GNOME/mutter/issues/");
if (priv->flags & META_CONTEXT_TEST_FLAG_TEST_CLIENT)
meta_ensure_test_client_path (*argc, *argv);
meta_wayland_override_display_name ("mutter-test-display");
#ifdef HAVE_XWAYLAND
meta_xwayland_override_display_number (512);
#endif
meta_context_set_plugin_gtype (context, META_TYPE_TEST_SHELL);
ensure_gsettings_memory_backend ();
return TRUE;
}
static MetaCompositorType
meta_context_test_get_compositor_type (MetaContext *context)
{
return META_COMPOSITOR_TYPE_WAYLAND;
}
static MetaX11DisplayPolicy
meta_context_test_get_x11_display_policy (MetaContext *context)
{
MetaContextTest *context_test = META_CONTEXT_TEST (context);
MetaContextTestPrivate *priv =
meta_context_test_get_instance_private (context_test);
if (priv->flags & META_CONTEXT_TEST_FLAG_NO_X11)
return META_X11_DISPLAY_POLICY_DISABLED;
else
return META_X11_DISPLAY_POLICY_ON_DEMAND;
}
static gboolean
meta_context_test_is_replacing (MetaContext *context)
{
return FALSE;
}
static gboolean
meta_context_test_setup (MetaContext *context,
GError **error)
{
MetaBackend *backend;
MetaSettings *settings;
if (!META_CONTEXT_CLASS (meta_context_test_parent_class)->setup (context,
error))
return FALSE;
backend = meta_context_get_backend (context);
settings = meta_backend_get_settings (backend);
meta_settings_override_experimental_features (settings);
meta_settings_enable_experimental_feature (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
return TRUE;
}
static MetaBackend *
create_nested_backend (MetaContext *context,
GError **error)
{
return g_initable_new (META_TYPE_BACKEND_TEST,
NULL, error,
"context", context,
NULL);
}
#ifdef HAVE_NATIVE_BACKEND
static MetaBackend *
create_headless_backend (MetaContext *context,
GError **error)
{
return g_initable_new (META_TYPE_BACKEND_NATIVE,
NULL, error,
"context", context,
"mode", META_BACKEND_NATIVE_MODE_HEADLESS,
NULL);
}
static MetaBackend *
create_native_backend (MetaContext *context,
GError **error)
{
return g_initable_new (META_TYPE_BACKEND_NATIVE,
NULL, error,
"context", context,
"mode", META_BACKEND_NATIVE_MODE_TEST,
NULL);
}
#endif /* HAVE_NATIVE_BACKEND */
static MetaBackend *
meta_context_test_create_backend (MetaContext *context,
GError **error)
{
MetaContextTest *context_test = META_CONTEXT_TEST (context);
MetaContextTestPrivate *priv =
meta_context_test_get_instance_private (context_test);
switch (priv->type)
{
case META_CONTEXT_TEST_TYPE_NESTED:
return create_nested_backend (context, error);
#ifdef HAVE_NATIVE_BACKEND
case META_CONTEXT_TEST_TYPE_HEADLESS:
return create_headless_backend (context, error);
case META_CONTEXT_TEST_TYPE_VKMS:
return create_native_backend (context, error);
#endif /* HAVE_NATIVE_BACKEND */
}
g_assert_not_reached ();
}
static void
meta_context_test_notify_ready (MetaContext *context)
{
}
#ifdef HAVE_X11
static gboolean
meta_context_test_is_x11_sync (MetaContext *context)
{
return !!g_getenv ("MUTTER_SYNC");
}
#endif
static gboolean
run_tests_idle (gpointer user_data)
{
MetaContext *context = user_data;
int ret;
g_signal_emit (context, signals[BEFORE_TESTS], 0);
if (g_signal_has_handler_pending (context, signals[RUN_TESTS], 0, TRUE))
{
g_signal_emit (context, signals[RUN_TESTS], 0, &ret);
g_assert (ret == 1 || ret == 0);
}
else
{
ret = g_test_run ();
}
g_signal_emit (context, signals[AFTER_TESTS], 0);
if (ret != 0)
{
GError *error;
error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
"One or more tests failed");
meta_context_terminate_with_error (context, error);
}
else
{
meta_context_terminate (context);
}
return G_SOURCE_REMOVE;
}
int
meta_context_test_run_tests (MetaContextTest *context_test,
MetaTestRunFlags flags)
{
MetaContext *context = META_CONTEXT (context_test);
g_autoptr (GError) error = NULL;
if (!meta_context_setup (context, &error))
{
if ((flags & META_TEST_RUN_FLAG_CAN_SKIP) &&
((g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
strstr (error->message, "No GPUs found")) ||
(g_error_matches (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR) &&
strstr (error->message, "Could not take control")) ||
(g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD) &&
strstr (error->message, "Could not take control"))))
{
g_printerr ("Test skipped: %s\n", error->message);
return 77;
}
else
{
g_printerr ("Test case failed to setup: %s\n", error->message);
return EXIT_FAILURE;
}
}
if (!meta_context_start (context, &error))
{
g_printerr ("Test case failed to start: %s\n", error->message);
return EXIT_FAILURE;
}
g_idle_add (run_tests_idle, context_test);
meta_context_notify_ready (context);
if (!meta_context_run_main_loop (context, &error))
{
g_printerr ("Test case failed: %s\n", error->message);
return EXIT_FAILURE;
}
else
{
return EXIT_SUCCESS;
}
}
void
meta_context_test_wait_for_x11_display (MetaContextTest *context_test)
{
MetaDisplay *display = meta_context_get_display (META_CONTEXT (context_test));
while (!meta_display_get_x11_display (display))
g_main_context_iteration (NULL, TRUE);
g_assert_nonnull (meta_display_get_x11_display (display));
}
/**
* meta_create_test_context: (skip)
*/
MetaContext *
meta_create_test_context (MetaContextTestType type,
MetaContextTestFlag flags)
{
MetaContextTest *context_test;
MetaContextTestPrivate *priv;
context_test = g_object_new (META_TYPE_CONTEXT_TEST,
"name", "Mutter Test",
NULL);
priv = meta_context_test_get_instance_private (context_test);
priv->type = type;
priv->flags = flags;
return META_CONTEXT (context_test);
}
static void
meta_context_test_class_init (MetaContextTestClass *klass)
{
MetaContextClass *context_class = META_CONTEXT_CLASS (klass);
context_class->configure = meta_context_test_configure;
context_class->get_compositor_type = meta_context_test_get_compositor_type;
context_class->get_x11_display_policy =
meta_context_test_get_x11_display_policy;
context_class->is_replacing = meta_context_test_is_replacing;
context_class->setup = meta_context_test_setup;
context_class->create_backend = meta_context_test_create_backend;
context_class->notify_ready = meta_context_test_notify_ready;
#ifdef HAVE_X11
context_class->is_x11_sync = meta_context_test_is_x11_sync;
#endif
signals[BEFORE_TESTS] =
g_signal_new ("before-tests",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE,
0);
signals[RUN_TESTS] =
g_signal_new ("run-tests",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_INT,
0);
signals[AFTER_TESTS] =
g_signal_new ("after-tests",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE,
0);
}
static void
meta_context_test_init (MetaContextTest *context_test)
{
GDBusProxy *proxy;
g_autoptr (GError) error = NULL;
g_autoptr (GVariant) ret = NULL;
proxy =
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
NULL,
"org.freedesktop.ColorManager",
"/org/freedesktop/ColorManager",
"org.freedesktop.DBus.Mock",
NULL, &error);
if (!proxy)
{
g_warning ("Failed to find mocked color manager system service, %s",
error->message);
return;
}
ret = g_dbus_proxy_call_sync (proxy,
"Reset",
NULL,
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL,
&error);
if (ret == NULL)
g_warning ("Failed to clear mocked color devices: %s", error->message);
}