diff --git a/build-aux/many-builds.py b/build-aux/many-builds.py index 9b72d979c6c8c58adf8900b0dd9f6842253b9dac..abbd5449a9c8d61ca58726a171414cf9377fc75d 100755 --- a/build-aux/many-builds.py +++ b/build-aux/many-builds.py @@ -53,6 +53,8 @@ _build/ coverage/ Build for host system with coverage doc/ Build for host system with gtk-doc and pandoc host-no-asan/ No AddressSanitizer, for use with valgrind + arm64/ Build for host system for arm64, as an + example of a non-x86 platform i386/ Build for host system for i386 """ @@ -298,6 +300,17 @@ class Environment: ] + args, ) + self.setup_one( + 'arm64', + dev_build + [ + '-Dintrospection=disabled', + '-Dmultiarch_tuple=aarch64-linux-gnu', + '--cross-file=build-aux/meson/arm64.txt', + ] + args, + # Host system doesn't necessarily have an arm64 toolchain + check=False, + ) + self.setup_one( 'i386', asan_dev_build + [ diff --git a/build-aux/meson/arm64.txt b/build-aux/meson/arm64.txt new file mode 100644 index 0000000000000000000000000000000000000000..afa1aed2ff05125f906151619a4f9285a122112c --- /dev/null +++ b/build-aux/meson/arm64.txt @@ -0,0 +1,41 @@ +# Copyright 2022-2025 Collabora Ltd. +# SPDX-License-Identifier: MIT +# +# Loosely based on the output of: +# /usr/share/meson/debcrossgen --arch arm64 + +[constants] +DEB_HOST_GNU_TYPE = 'aarch64-linux-gnu' +DEB_HOST_MULTIARCH = 'aarch64-linux-gnu' + +[binaries] +c = DEB_HOST_GNU_TYPE + '-gcc' +cpp = DEB_HOST_GNU_TYPE + '-g++' +ar = DEB_HOST_GNU_TYPE + '-ar' +strip = DEB_HOST_GNU_TYPE + '-strip' +objcopy = DEB_HOST_GNU_TYPE + '-objcopy' +ld = DEB_HOST_GNU_TYPE + '-ld' +pkgconfig = DEB_HOST_GNU_TYPE + '-pkg-config' +pkg-config = DEB_HOST_GNU_TYPE + '-pkg-config' +cmake = 'cmake' +cups-config = 'cups-config' +sdl2-config = 'sdl2-config' + +[built-in options] +libdir = 'lib' / DEB_HOST_MULTIARCH + +[properties] +# This assumes that if we will run tests, we have qemu-static installed +needs_exe_wrapper = false + +[cmake] +CMAKE_C_COMPILER = DEB_HOST_GNU_TYPE + '-gcc' +CMAKE_CXX_COMPILER = DEB_HOST_GNU_TYPE + '-g++' +CMAKE_SYSTEM_NAME = 'Linux' +CMAKE_SYSTEM_PROCESSOR = 'aarch64' + +[host_machine] +system = 'linux' +cpu_family = 'aarch64' +cpu = 'arm64' +endian = 'little' diff --git a/config.h.in b/config.h.in index 27b06c306afdd8004733223619f84bf3b52267aa..016f10f0b47465f1eec546616b0b155d90e0fde7 100644 --- a/config.h.in +++ b/config.h.in @@ -7,6 +7,7 @@ #define _SRT_SONAME "libsteam-runtime-tools-@api_major@.so.@abi_major" #define _GNU_SOURCE 1 #mesondefine _SRT_MULTIARCH +#mesondefine _SRT_TESTS_STRICT #mesondefine VERSION /* Allow using stuff from Flatpak with minimal modifications */ diff --git a/meson.build b/meson.build index fcf4b0e60092bc0f8732d260466bfcb5c3b0da34..346cc565febface673b0fa1073aff7f3fe27c3c3 100644 --- a/meson.build +++ b/meson.build @@ -262,10 +262,17 @@ elif host_machine.cpu_family() == 'x86' multiarch = 'i386-linux-gnu' elif host_machine.cpu_family() == 'aarch64' and host_machine.endian() == 'little' multiarch = 'aarch64-linux-gnu' +elif get_option('werror') + # Some of our test coverage is skipped if we don't know the multiarch tuple + error('-Dmultiarch_tuple is required when building with --werror on an unknown CPU') else multiarch = '' endif +if get_option('werror') + conf_data.set('_SRT_TESTS_STRICT', true) +endif + if multiarch != '' conf_data.set_quoted('_SRT_MULTIARCH', multiarch) endif diff --git a/pressure-vessel/adverb-preload.c b/pressure-vessel/adverb-preload.c index 415b4ee8e7efe463b40283d83db3aec9dad1fe89..2685f6fbfad45f9298ea1ca3da8ec81c6cd411ca 100644 --- a/pressure-vessel/adverb-preload.c +++ b/pressure-vessel/adverb-preload.c @@ -9,11 +9,22 @@ #include "supported-architectures.h" #include "utils.h" -/* Indexed by PreloadVariableIndex */ -static const char *preload_variables[] = +const PvPreloadVariable pv_preload_variables[] = { - "LD_AUDIT", - "LD_PRELOAD", + [PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT] = { + .variable = "LD_AUDIT", + .adverb_option = "--ld-audit", + /* "The items in the list are colon-separated, and there is no support + * for escaping the separator." —ld.so(8) */ + .separators = ":", + }, + [PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD] = { + .variable = "LD_PRELOAD", + .adverb_option = "--ld-preload", + /* "The items of the list can be separated by spaces or colons, and + * there is no support for escaping either separator." —ld.so(8) */ + .separators = ": ", + }, }; static gpointer @@ -45,7 +56,7 @@ pv_adverb_set_up_preload_modules (FlatpakBwrap *wrapped_command, gsize n_preload_modules, GError **error) { - GPtrArray *preload_search_paths[G_N_ELEMENTS (preload_variables)] = { NULL }; + GPtrArray *preload_search_paths[G_N_ELEMENTS (pv_preload_variables)] = { NULL }; gsize i; /* Iterate through all modules, populating preload_search_paths */ @@ -155,11 +166,11 @@ pv_adverb_set_up_preload_modules (FlatpakBwrap *wrapped_command, /* Serialize search_paths[PRELOAD_VARIABLE_INDEX_LD_AUDIT] into * LD_AUDIT, etc. */ - for (i = 0; i < G_N_ELEMENTS (preload_variables); i++) + for (i = 0; i < G_N_ELEMENTS (pv_preload_variables); i++) { GPtrArray *search_path = preload_search_paths[i]; g_autoptr(GString) buffer = g_string_new (""); - const char *variable = preload_variables[i]; + const char *variable = pv_preload_variables[i].variable; if (search_path != NULL) g_ptr_array_foreach (search_path, (GFunc) append_to_search_path, buffer); diff --git a/pressure-vessel/adverb-preload.h b/pressure-vessel/adverb-preload.h index 53166178163d6a409e71189825fea2cb59f6dd23..bd9c578dcfb66ac6c30804e1136551fbd2b05fed 100644 --- a/pressure-vessel/adverb-preload.h +++ b/pressure-vessel/adverb-preload.h @@ -18,6 +18,15 @@ typedef enum PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, } PvPreloadVariableIndex; +typedef struct +{ + const char *variable; + const char *adverb_option; + const char *separators; +} PvPreloadVariable; + +extern const PvPreloadVariable pv_preload_variables[2]; + #define PV_UNSPECIFIED_ABI (G_MAXSIZE) typedef struct @@ -28,14 +37,25 @@ typedef struct gsize abi_index; } PvAdverbPreloadModule; +#define PV_ADVERB_PRELOAD_MODULE_INIT \ +{ \ + .name = NULL, \ + .index_in_preload_variables = 0, \ + .abi_index = PV_UNSPECIFIED_ABI, \ +} + static inline void pv_adverb_preload_module_clear (gpointer p) { PvAdverbPreloadModule *self = p; + PvAdverbPreloadModule blank = PV_ADVERB_PRELOAD_MODULE_INIT; g_free (self->name); + *self = blank; } +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (PvAdverbPreloadModule, pv_adverb_preload_module_clear) + gboolean pv_adverb_set_up_preload_modules (FlatpakBwrap *wrapped_command, PvPerArchDirs *lib_temp_dirs, const PvAdverbPreloadModule *preload_modules, diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build index 5bb38e9cfb0a91f4070727211b76daa907dc846c..59bfe47c78c6278479792b1d982977231ac798ae 100644 --- a/pressure-vessel/meson.build +++ b/pressure-vessel/meson.build @@ -71,6 +71,8 @@ enums = gnome.mkenums_simple( pressure_vessel_utils = static_library( 'pressure-vessel-utils', sources : [ + 'adverb-preload.c', + 'adverb-preload.h', 'flatpak-bwrap.c', 'flatpak-bwrap-private.h', 'flatpak-utils-base.c', @@ -106,8 +108,6 @@ pressure_vessel_utils_dep = declare_dependency( pressure_vessel_adverb_lib = static_library( 'pressure-vessel-adverb-lib', sources : [ - 'adverb-preload.c', - 'adverb-preload.h', 'adverb-sdl.c', 'adverb-sdl.h', 'per-arch-dirs.c', diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index ef0f5881975b4fda71808d54a0c1d519d341fd58..408194767e530e618bce88e8db6a6f07c072d781 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -96,7 +96,9 @@ struct _PvRuntime PvGraphicsProvider *interpreter_host_provider; EnumerationThread indep_thread; EnumerationThread host_thread; +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 EnumerationThread *arch_host_threads; +#endif EnumerationThread *arch_threads; SrtDirentCompareFunc arbitrary_dirent_order; GCompareFunc arbitrary_str_order; @@ -1519,6 +1521,7 @@ pv_runtime_initable_init (GInitable *initable, self->interpreter_host_provider, "real-host"); +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 self->arch_host_threads = g_new0 (EnumerationThread, PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST); @@ -1527,6 +1530,7 @@ pv_runtime_initable_init (GInitable *initable, &pv_multiarch_as_emulator_details[i], self->flags, self->interpreter_host_provider); +#endif } self->arch_threads = g_new0 (EnumerationThread, @@ -1857,8 +1861,10 @@ pv_runtime_dispose (GObject *object) g_clear_object (&self->host_root); enumeration_thread_clear (&self->indep_thread); enumeration_thread_clear (&self->host_thread); +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 enumeration_threads_clear (&self->arch_host_threads, PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST); +#endif enumeration_threads_clear (&self->arch_threads, PV_N_SUPPORTED_ARCHITECTURES); @@ -7101,6 +7107,7 @@ collect_dri_drivers (PvRuntime *self, return TRUE; } +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 /* * @search_path: (inout): */ @@ -7174,6 +7181,7 @@ pv_append_host_dri_library_paths (PvRuntime *self, while (_srt_hash_table_iter_next (&iter, &drivers_path, NULL)) pv_search_path_append (search_path, drivers_path); } +#endif /* * Returns: (element-type IcdDetails): @@ -7495,12 +7503,14 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self, if (self->flags & PV_RUNTIME_FLAGS_SINGLE_THREAD) { system_info = pv_graphics_provider_create_system_info (self->provider); + if (self->interpreter_host_provider != NULL) host_system_info = pv_graphics_provider_create_system_info (self->interpreter_host_provider); } else { system_info = g_object_ref (enumeration_thread_join (&self->indep_thread)); + if (self->interpreter_host_provider != NULL) host_system_info = g_object_ref (enumeration_thread_join (&self->host_thread)); } @@ -7781,6 +7791,7 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self, { g_assert (pv_multiarch_as_emulator_tuples[PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST] == NULL); +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST; i++) { SrtSystemInfo *arch_system_info; @@ -7795,6 +7806,7 @@ pv_runtime_use_provider_graphics_stack (PvRuntime *self, pv_multiarch_as_emulator_tuples[i], dri_path); } +#endif } part_timer = _srt_profiling_start ("Finishing graphics stack capture"); diff --git a/pressure-vessel/wrap-context.c b/pressure-vessel/wrap-context.c index 3b26215767e1f76f7f9bb80d76f47c417cfb791d..dd711208e75810a0109df8766afacd7d9f8a7d99 100644 --- a/pressure-vessel/wrap-context.c +++ b/pressure-vessel/wrap-context.c @@ -192,17 +192,17 @@ opt_ignored_cb (const gchar *option_name, static gboolean opt_ld_something (PvWrapOptions *self, - PreloadVariableIndex which, + PvPreloadVariableIndex which, const char *value, - const char *separators, + gboolean split, GError **error) { g_auto(GStrv) tokens = NULL; size_t i; - if (separators != NULL) + if (split) { - tokens = g_strsplit_set (value, separators, 0); + tokens = g_strsplit_set (value, pv_preload_variables[which].separators, 0); } else { @@ -230,8 +230,8 @@ opt_ld_audit_cb (const gchar *option_name, gpointer data, GError **error) { - return opt_ld_something (data, PRELOAD_VARIABLE_INDEX_LD_AUDIT, - value, NULL, error); + return opt_ld_something (data, PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, + value, FALSE, error); } static gboolean @@ -240,10 +240,8 @@ opt_ld_audits_cb (const gchar *option_name, gpointer data, GError **error) { - /* "The items in the list are colon-separated, and there is no support - * for escaping the separator." —ld.so(8) */ - return opt_ld_something (data, PRELOAD_VARIABLE_INDEX_LD_AUDIT, - value, ":", error); + return opt_ld_something (data, PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, + value, TRUE, error); } static gboolean @@ -252,8 +250,8 @@ opt_ld_preload_cb (const gchar *option_name, gpointer data, GError **error) { - return opt_ld_something (data, PRELOAD_VARIABLE_INDEX_LD_PRELOAD, - value, NULL, error); + return opt_ld_something (data, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + value, FALSE, error); } static gboolean @@ -262,10 +260,8 @@ opt_ld_preloads_cb (const gchar *option_name, gpointer data, GError **error) { - /* "The items of the list can be separated by spaces or colons, and - * there is no support for escaping either separator." —ld.so(8) */ - return opt_ld_something (data, PRELOAD_VARIABLE_INDEX_LD_PRELOAD, - value, ": ", error); + return opt_ld_something (data, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + value, TRUE, error); } static gboolean diff --git a/pressure-vessel/wrap-context.h b/pressure-vessel/wrap-context.h index 56d5bcfd7e3ffce142bfb117903903050bbd3ccd..17d2db2c2821faf7654445fe116a51af3e1e9b35 100644 --- a/pressure-vessel/wrap-context.h +++ b/pressure-vessel/wrap-context.h @@ -11,6 +11,7 @@ #include "steam-runtime-tools/resolve-in-sysroot-internal.h" #include "steam-runtime-tools/utils-internal.h" +#include "pressure-vessel/adverb-preload.h" #include "pressure-vessel/flatpak-exports-private.h" #include "pressure-vessel/wrap-interactive.h" @@ -39,15 +40,9 @@ typedef enum TRISTATE_MAYBE } Tristate; -typedef enum -{ - PRELOAD_VARIABLE_INDEX_LD_AUDIT, - PRELOAD_VARIABLE_INDEX_LD_PRELOAD, -} PreloadVariableIndex; - typedef struct { - PreloadVariableIndex which; + PvPreloadVariableIndex which; gchar *preload; } WrapPreloadModule; diff --git a/pressure-vessel/wrap-setup.c b/pressure-vessel/wrap-setup.c index 2dc46ccf31c086dfbd6a450c19265a8ed4e3054c..7e31e55cf54cfd8da2e95e0c4cbe4847f6c4d0e7 100644 --- a/pressure-vessel/wrap-setup.c +++ b/pressure-vessel/wrap-setup.c @@ -33,6 +33,7 @@ #include <string.h> +#include "adverb-preload.h" #include "bwrap.h" #include "exports.h" #include "flatpak-run-dbus-private.h" @@ -710,12 +711,16 @@ append_preload_per_architecture (GPtrArray *argv, FlatpakExports *exports) { g_autoptr(SrtSystemInfo) system_info = srt_system_info_new (NULL); + gsize n_supported_architectures = PV_N_SUPPORTED_ARCHITECTURES; gsize i; - if (system_info == NULL) - system_info = srt_system_info_new (NULL); + if (flags & PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE) + { + G_STATIC_ASSERT (PV_N_SUPPORTED_ARCHITECTURES >= 1); + n_supported_architectures = 1; + } - for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES; i++) + for (i = 0; i < n_supported_architectures; i++) { g_autoptr(GString) mock_path = NULL; g_autoptr(SrtLibrary) details = NULL; @@ -744,7 +749,6 @@ append_preload_per_architecture (GPtrArray *argv, /* As a mock ${PLATFORM}, use the first one listed. */ platform = pv_multiarch_details[i].platforms[0]; #else - multiarch_tuple = "mock-multiarch-tuple"; platform = "mock"; #endif /* As a mock ${LIB}, behave like Debian or the fdo SDK. */ @@ -866,10 +870,7 @@ append_preload_basename (GPtrArray *argv, /** * pv_wrap_append_preload: * @argv: (element-type filename): Array of command-line options to populate - * @variable: (type filename): Environment variable from which this - * preload module was taken, either `LD_AUDIT` or `LD_PRELOAD` - * @option: (type filename): Command-line option to add to @argv, - * either `--ld-audit` or `--ld-preload` + * @which: Either `LD_AUDIT` or `LD_PRELOAD` * @preload: (type filename): Path of preloadable module in current * namespace, possibly including special ld.so tokens such as `$LIB`, * or basename of a preloadable module to be found in the standard @@ -886,8 +887,7 @@ append_preload_basename (GPtrArray *argv, */ void pv_wrap_append_preload (GPtrArray *argv, - const char *variable, - const char *option, + PvPreloadVariableIndex which, const char *preload, GStrv env, PvAppendPreloadFlags flags, @@ -896,11 +896,17 @@ pv_wrap_append_preload (GPtrArray *argv, { SrtLoadableKind kind; SrtLoadableFlags loadable_flags; + const char *variable; + const char *option; g_return_if_fail (argv != NULL); - g_return_if_fail (option != NULL); g_return_if_fail (preload != NULL); g_return_if_fail (runtime == NULL || PV_IS_RUNTIME (runtime)); + g_return_if_fail (which >= 0); + g_return_if_fail (which < G_N_ELEMENTS (pv_preload_variables)); + + variable = pv_preload_variables[which].variable; + option = pv_preload_variables[which].adverb_option; if (strstr (preload, "gtk3-nocsd") != NULL) { diff --git a/pressure-vessel/wrap-setup.h b/pressure-vessel/wrap-setup.h index a690e3cbf67d81b16afd022418ee2a3fd9f4840d..936314a4d0901c4947798b462bc6b112340518ba 100644 --- a/pressure-vessel/wrap-setup.h +++ b/pressure-vessel/wrap-setup.h @@ -26,6 +26,7 @@ #include "steam-runtime-tools/env-overlay-internal.h" #include "steam-runtime-tools/utils-internal.h" +#include "adverb-preload.h" #include "bwrap.h" #include "flatpak-bwrap-private.h" #include "flatpak-exports-private.h" @@ -66,6 +67,10 @@ void pv_wrap_move_into_scope (const char *steam_app_id); * @PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX: The game will be run in * a Flatpak subsandbox * @PV_APPEND_PRELOAD_FLAGS_REMOVE_GAME_OVERLAY: Disable the Steam Overlay + * @PV_APPEND_PRELOAD_FLAGS_IN_UNIT_TESTS: Normalize $LIB and $PLATFORM, + * for unit testing + * @PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE: Behave as though there is + * only one architecture supported, for test coverage * @PV_APPEND_PRELOAD_FLAGS_NONE: None of the above * * Flags affecting the behaviour of pv_wrap_append_preload(). @@ -75,12 +80,12 @@ typedef enum PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX = (1 << 0), PV_APPEND_PRELOAD_FLAGS_REMOVE_GAME_OVERLAY = (1 << 1), PV_APPEND_PRELOAD_FLAGS_IN_UNIT_TESTS = (1 << 2), + PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE = (1 << 3), PV_APPEND_PRELOAD_FLAGS_NONE = 0 } PvAppendPreloadFlags; void pv_wrap_append_preload (GPtrArray *argv, - const char *variable, - const char *option, + PvPreloadVariableIndex which, const char *preload, GStrv env, PvAppendPreloadFlags flags, diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index 00aacc9a1adf84cc20b02c37a295a4c3c89aea9f..eddd59e0057a40e780ca0eb150dc2ba14c7c7560 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -66,16 +66,6 @@ static const GDebugKey pv_debug_keys[] = { "container", PV_WRAP_LOG_FLAGS_CONTAINER }, }; -static const struct -{ - const char *variable; - const char *adverb_option; -} preload_options[] = -{ - [PRELOAD_VARIABLE_INDEX_LD_AUDIT] = { "LD_AUDIT", "--ld-audit" }, - [PRELOAD_VARIABLE_INDEX_LD_PRELOAD] = { "LD_PRELOAD", "--ld-preload" }, -}; - #define usage_error(...) _srt_log_failure (__VA_ARGS__) int @@ -851,10 +841,9 @@ main (int argc, j); g_assert (module->which >= 0); - g_assert (module->which < G_N_ELEMENTS (preload_options)); + g_assert (module->which < G_N_ELEMENTS (pv_preload_variables)); pv_wrap_append_preload (adverb_preload_argv, - preload_options[module->which].variable, - preload_options[module->which].adverb_option, + module->which, module->preload, environ, append_preload_flags, diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h index 732a9837da31c81c20566ded8f5815d3afddd601..a7d8e098ce8c1a2feaa7dd50ab10d5f564169e9f 100644 --- a/steam-runtime-tools/utils-internal.h +++ b/steam-runtime-tools/utils-internal.h @@ -604,6 +604,23 @@ gboolean _srt_string_read_fd_until_eof (GString *buf, int fd, GError **error); +/* + * _srt_string_ends_with_len: + * @str: A #GString + * @suffix: A suffix + * @len: Length of suffix + * + * Returns: %TRUE if @str ends with @suffix + */ +static inline gboolean +_srt_string_ends_with_len (const GString *str, + const char *suffix, + gsize len) +{ + return (str->len >= len + && memcmp (str->str + str->len - len, suffix, len) == 0); +} + /* * _srt_string_ends_with: * @str: A #GString @@ -615,10 +632,7 @@ static inline gboolean _srt_string_ends_with (const GString *str, const char *suffix) { - size_t len = strlen (suffix); - - return (str->len >= len - && strcmp (str->str + str->len - len, suffix) == 0); + return _srt_string_ends_with_len (str, suffix, strlen (suffix)); } gboolean _srt_is_identifier (const char *name); diff --git a/tests/pressure-vessel/adverb-preload.c b/tests/pressure-vessel/adverb-preload.c index aea1c3cd7c5e8b1951c8c93046638959d495bbe0..a50fc2a01425fc83b0b9a6eda291d446a18343e9 100644 --- a/tests/pressure-vessel/adverb-preload.c +++ b/tests/pressure-vessel/adverb-preload.c @@ -22,34 +22,57 @@ typedef struct typedef struct { - int unused; + gboolean can_discover_platform; } Config; +static const Config default_config = { + .can_discover_platform = TRUE, +}; + static void setup (Fixture *f, gconstpointer context) { - G_GNUC_UNUSED const Config *config = context; + const Config *config = context; g_autoptr(GError) local_error = NULL; gsize i; + if (config == NULL) + config = &default_config; + f->old_fds = tests_check_fd_leaks_enter (); f->bwrap = flatpak_bwrap_new (flatpak_bwrap_empty_env); - f->lib_temp_dirs = pv_per_arch_dirs_new (&local_error); - if (f->lib_temp_dirs == NULL) + if (config->can_discover_platform) { - g_test_skip (local_error->message); - return; - } + f->lib_temp_dirs = pv_per_arch_dirs_new (&local_error); +#ifdef _SRT_TESTS_STRICT + /* We allow this to fail because it might fail on particularly strange + * OS configurations, but for platforms we actively support, + * we expect it to work */ + g_assert_no_error (local_error); + g_assert_nonnull (f->lib_temp_dirs); +#endif + + if (f->lib_temp_dirs == NULL) + { + g_test_skip (local_error->message); + return; + } - g_test_message ("Cross-platform module prefix: %s", - f->lib_temp_dirs->libdl_token_path); + g_test_message ("Cross-platform module prefix: %s", + f->lib_temp_dirs->libdl_token_path); - for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES; i++) - g_test_message ("Concrete path for %s architecture: %s", - pv_multiarch_tuples[i], - f->lib_temp_dirs->abi_paths[i]); + for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES; i++) + g_test_message ("Concrete path for %s architecture: %s", + pv_multiarch_tuples[i], + f->lib_temp_dirs->abi_paths[i]); + + } + else + { + g_test_message ("Pretending we cannot use $LIB/$PLATFORM"); + } } static void @@ -69,15 +92,41 @@ test_basic (Fixture *f, { static const PvAdverbPreloadModule modules[] = { - { (char *) "", PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, 0 }, - { (char *) "/opt/libaudit.so", PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, 0 }, - { (char *) "", PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/unspecified.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, - PV_UNSPECIFIED_ABI }, - { (char *) "/opt/libpreload2.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/unspecified2.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, - PV_UNSPECIFIED_ABI }, + { + .name = (char *) "", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, + .abi_index = 0, + }, + { + .name = (char *) "/opt/libaudit.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, + .abi_index = 0, + }, + { + .name = (char *) "", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/unspecified.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/libpreload2.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/unspecified2.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, }; g_autoptr(GError) local_error = NULL; g_autoptr(GString) expected = g_string_new (""); @@ -85,9 +134,6 @@ test_basic (Fixture *f, gboolean ret; gsize i; - if (f->lib_temp_dirs == NULL) - return; - ret = pv_adverb_set_up_preload_modules (f->bwrap, f->lib_temp_dirs, modules, @@ -101,20 +147,35 @@ test_basic (Fixture *f, i = 0; g_string_assign (expected, "LD_AUDIT="); - g_string_append_printf (expected, "%s/libaudit.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/libaudit.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/libaudit.so"); + g_assert_cmpstr (f->bwrap->envp[i], ==, expected->str); i++; /* Order is preserved, independent of whether an ABI is specified */ g_string_assign (expected, "LD_PRELOAD="); - g_string_append_printf (expected, "%s/libpreload.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/libpreload.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/libpreload.so"); + g_string_append_c (expected, ':'); g_string_append (expected, "/opt/unspecified.so"); g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/libpreload2.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/libpreload2.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/libpreload2.so"); + g_string_append_c (expected, ':'); g_string_append (expected, "/opt/unspecified2.so"); g_assert_cmpstr (f->bwrap->envp[i], ==, expected->str); @@ -126,6 +187,9 @@ test_basic (Fixture *f, { g_autofree gchar *target = NULL; + if (f->lib_temp_dirs == NULL) + continue; + /* Empty module entries are ignored */ if (modules[i].name[0] == '\0') continue; @@ -160,11 +224,23 @@ test_biarch (Fixture *f, #if PV_N_SUPPORTED_ARCHITECTURES >= 2 static const PvAdverbPreloadModule modules[] = { - { (char *) "/opt/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, + { + .name = (char *) "/opt/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, /* In practice x86_64-linux-gnu */ - { (char *) "/opt/lib0/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, + { + .name = (char *) "/opt/lib0/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, /* In practice i386-linux-gnu */ - { (char *) "/opt/lib1/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 1 }, + { + .name = (char *) "/opt/lib1/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 1, + }, }; g_autoptr(GError) local_error = NULL; g_autoptr(GString) expected = g_string_new (""); @@ -172,9 +248,6 @@ test_biarch (Fixture *f, gboolean ret; gsize i; - if (f->lib_temp_dirs == NULL) - return; - ret = pv_adverb_set_up_preload_modules (f->bwrap, f->lib_temp_dirs, modules, @@ -194,8 +267,19 @@ test_biarch (Fixture *f, g_string_assign (expected, "LD_PRELOAD="); g_string_append (expected, "/opt/libpreload.so"); g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/libpreload.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + { + g_string_append_printf (expected, "%s/libpreload.so", + f->lib_temp_dirs->libdl_token_path); + } + else + { + g_string_append (expected, "/opt/lib0/libpreload.so"); + g_string_append_c (expected, ':'); + g_string_append (expected, "/opt/lib1/libpreload.so"); + } + g_assert_cmpstr (f->bwrap->envp[i], ==, expected->str); i++; @@ -205,6 +289,9 @@ test_biarch (Fixture *f, { g_autofree gchar *target = NULL; + if (f->lib_temp_dirs == NULL) + continue; + g_string_assign (path, f->lib_temp_dirs->abi_paths[i]); g_string_append_c (path, G_DIR_SEPARATOR); g_string_append (path, "libpreload.so"); @@ -236,14 +323,26 @@ test_gameoverlayrenderer (Fixture *f, #if defined(__x86_64__) || defined(__i386__) static const PvAdverbPreloadModule modules[] = { - { (char *) "/opt/steam/some-other-abi/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/steam/some-other-abi/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, + { + .name = (char *) "/opt/steam/some-other-abi/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/steam/some-other-abi/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, }; g_autoptr(GError) local_error = NULL; g_autoptr(GString) expected = g_string_new (""); @@ -253,9 +352,6 @@ test_gameoverlayrenderer (Fixture *f, G_STATIC_ASSERT (PV_N_SUPPORTED_ARCHITECTURES == 2); - if (f->lib_temp_dirs == NULL) - return; - ret = pv_adverb_set_up_preload_modules (f->bwrap, f->lib_temp_dirs, modules, @@ -271,8 +367,19 @@ test_gameoverlayrenderer (Fixture *f, g_string_assign (expected, "LD_PRELOAD="); g_string_append (expected, "/opt/steam/some-other-abi/gameoverlayrenderer.so"); g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/gameoverlayrenderer.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + { + g_string_append_printf (expected, "%s/gameoverlayrenderer.so", + f->lib_temp_dirs->libdl_token_path); + } + else + { + g_string_append (expected, "/opt/steam/ubuntu12_32/gameoverlayrenderer.so"); + g_string_append_c (expected, ':'); + g_string_append (expected, "/opt/steam/ubuntu12_64/gameoverlayrenderer.so"); + } + g_string_append_c (expected, ':'); g_string_append (expected, "/opt/steam/some-other-abi/gameoverlayrenderer.so"); g_assert_cmpstr (f->bwrap->envp[i], ==, expected->str); @@ -284,6 +391,9 @@ test_gameoverlayrenderer (Fixture *f, { g_autofree gchar *target = NULL; + if (f->lib_temp_dirs == NULL) + continue; + g_string_assign (path, f->lib_temp_dirs->abi_paths[i]); g_string_append_c (path, G_DIR_SEPARATOR); g_string_append (path, "gameoverlayrenderer.so"); @@ -313,33 +423,79 @@ test_repetition (Fixture *f, { static const PvAdverbPreloadModule modules[] = { - { (char *) "/opt/lib0/libfirst.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/lib0/one/same-basename.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/lib0/two/same-basename.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/lib0/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, + { + .name = (char *) "/opt/lib0/libfirst.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/lib0/one/same-basename.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/lib0/two/same-basename.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/lib0/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, #if PV_N_SUPPORTED_ARCHITECTURES > 1 - { (char *) "/opt/lib1/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 1 }, + { + .name = (char *) "/opt/lib1/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 1, + }, #endif #if defined(__x86_64__) || defined(__i386__) - { (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, + { + .name = (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, #endif - { (char *) "/opt/lib0/libmiddle.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, - { (char *) "/opt/lib0/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, + { + .name = (char *) "/opt/lib0/libmiddle.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, + { + .name = (char *) "/opt/lib0/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, #if PV_N_SUPPORTED_ARCHITECTURES > 1 - { (char *) "/opt/lib1/libpreload.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 1 }, + { + .name = (char *) "/opt/lib1/libpreload.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 1, + }, #endif #if defined(__x86_64__) || defined(__i386__) - { (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, - { (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", - PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, PV_UNSPECIFIED_ABI }, + { + .name = (char *) "/opt/steam/ubuntu12_32/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, + { + .name = (char *) "/opt/steam/ubuntu12_64/gameoverlayrenderer.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = PV_UNSPECIFIED_ABI, + }, #endif - { (char *) "/opt/lib0/liblast.so", PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, 0 }, + { + .name = (char *) "/opt/lib0/liblast.so", + .index_in_preload_variables = PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, + .abi_index = 0, + }, }; g_autoptr(GError) local_error = NULL; g_autoptr(GString) expected = g_string_new (""); @@ -347,9 +503,6 @@ test_repetition (Fixture *f, gboolean ret; gsize i; - if (f->lib_temp_dirs == NULL) - return; - ret = pv_adverb_set_up_preload_modules (f->bwrap, f->lib_temp_dirs, modules, @@ -363,30 +516,95 @@ test_repetition (Fixture *f, i = 0; g_string_assign (expected, "LD_PRELOAD="); - g_string_append_printf (expected, "%s/libfirst.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/libfirst.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/lib0/libfirst.so"); + g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/same-basename.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/same-basename.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/lib0/one/same-basename.so"); + g_string_append_c (expected, ':'); /* We don't do the per-architecture split if there's a basename * collision */ g_string_append (expected, "/opt/lib0/two/same-basename.so"); g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/libpreload.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + { + g_string_append_printf (expected, "%s/libpreload.so", + f->lib_temp_dirs->libdl_token_path); + } + else + { + g_string_append (expected, "/opt/lib0/libpreload.so"); +#if PV_N_SUPPORTED_ARCHITECTURES > 1 + g_string_append_c (expected, ':'); + g_string_append (expected, "/opt/lib1/libpreload.so"); +#endif + } + #if defined(__x86_64__) || defined(__i386__) g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/gameoverlayrenderer.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + { + g_string_append_printf (expected, "%s/gameoverlayrenderer.so", + f->lib_temp_dirs->libdl_token_path); + } + else + { + g_string_append (expected, "/opt/steam/ubuntu12_32/gameoverlayrenderer.so"); + g_string_append_c (expected, ':'); + g_string_append (expected, "/opt/steam/ubuntu12_64/gameoverlayrenderer.so"); + } #endif + g_string_append_c (expected, ':'); - g_string_append_printf (expected, "%s/libmiddle.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + g_string_append_printf (expected, "%s/libmiddle.so", + f->lib_temp_dirs->libdl_token_path); + else + g_string_append (expected, "/opt/lib0/libmiddle.so"); + g_string_append_c (expected, ':'); - /* The duplicates don't appear in the search path a second time */ - g_string_append_printf (expected, "%s/liblast.so", - f->lib_temp_dirs->libdl_token_path); + + if (f->lib_temp_dirs != NULL) + { + /* If we are able to split up the modules by architecture, + * then the duplicates don't appear in the search path a second time */ + g_string_append_printf (expected, "%s/liblast.so", + f->lib_temp_dirs->libdl_token_path); + } + else + { + /* If we were unable to split up the modules by architecture, + * we change as little as possible, so in this case we do not + * deduplicate */ + g_string_append (expected, "/opt/lib0/libpreload.so"); + g_string_append_c (expected, ':'); +#if PV_N_SUPPORTED_ARCHITECTURES > 1 + g_string_append (expected, "/opt/lib1/libpreload.so"); + g_string_append_c (expected, ':'); +#endif +#if defined(__x86_64__) || defined(__i386__) + g_string_append (expected, "/opt/steam/ubuntu12_32/gameoverlayrenderer.so"); + g_string_append_c (expected, ':'); + g_string_append (expected, "/opt/steam/ubuntu12_64/gameoverlayrenderer.so"); + g_string_append_c (expected, ':'); +#endif + + g_string_append (expected, "/opt/lib0/liblast.so"); + } + g_assert_cmpstr (f->bwrap->envp[i], ==, expected->str); i++; @@ -398,6 +616,9 @@ test_repetition (Fixture *f, { gsize j; + if (f->lib_temp_dirs == NULL) + continue; + for (j = 0; j < G_N_ELEMENTS (modules); j++) { g_autofree gchar *target = NULL; @@ -434,6 +655,9 @@ test_repetition (Fixture *f, { g_autofree gchar *target = NULL; + if (f->lib_temp_dirs == NULL) + continue; + g_string_assign (path, f->lib_temp_dirs->abi_paths[i]); g_string_append_c (path, G_DIR_SEPARATOR); g_string_append (path, "gameoverlayrenderer.so"); @@ -450,6 +674,10 @@ test_repetition (Fixture *f, #endif } +static const Config cannot_discover_platform = { + .can_discover_platform = FALSE, +}; + int main (int argc, char **argv) @@ -462,14 +690,21 @@ main (int argc, g_setenv ("PRESSURE_VESSEL_TEST_STANDARDIZE_PLATFORM", "1", TRUE); _srt_tests_init (&argc, &argv, NULL); - g_test_add ("/basic", Fixture, NULL, - setup, test_basic, teardown); - g_test_add ("/biarch", Fixture, NULL, - setup, test_biarch, teardown); - g_test_add ("/gameoverlayrenderer", Fixture, NULL, - setup, test_gameoverlayrenderer, teardown); - g_test_add ("/repetition", Fixture, NULL, - setup, test_repetition, teardown); + +#define add_test(name, function) \ + do { \ + g_test_add (name, \ + Fixture, NULL, \ + setup, function, teardown); \ + g_test_add (name "/cannot-discover-platform", \ + Fixture, &cannot_discover_platform, \ + setup, function, teardown); \ + } while (0) + + add_test ("/basic", test_basic); + add_test ("/biarch", test_biarch); + add_test ("/gameoverlayrenderer", test_gameoverlayrenderer); + add_test ("/repetition", test_repetition); return g_test_run (); } diff --git a/tests/pressure-vessel/adverb-sdl.c b/tests/pressure-vessel/adverb-sdl.c index d6fde6ef8382bbc0591199b871ee950757854901..207f3c4b877ff37c9d00a225ab2e6210b91ee9ad 100644 --- a/tests/pressure-vessel/adverb-sdl.c +++ b/tests/pressure-vessel/adverb-sdl.c @@ -43,6 +43,13 @@ setup (Fixture *f, f->old_fds = tests_check_fd_leaks_enter (); f->bwrap = flatpak_bwrap_new (flatpak_bwrap_empty_env); f->lib_temp_dirs = pv_per_arch_dirs_new (&f->lib_temp_dirs_error); +#ifdef _SRT_TESTS_STRICT + /* We allow this to fail because it might fail on particularly strange + * OS configurations, but for platforms we actively support, + * we expect it to work */ + g_assert_no_error (f->lib_temp_dirs_error); + g_assert_nonnull (f->lib_temp_dirs); +#endif if (f->lib_temp_dirs != NULL) { diff --git a/tests/pressure-vessel/wrap-setup.c b/tests/pressure-vessel/wrap-setup.c index d5cf0330e7e6f9d767fe58a36643c769ae4609be..c238b8af06900e43ec96e1a75602aba15b34726b 100644 --- a/tests/pressure-vessel/wrap-setup.c +++ b/tests/pressure-vessel/wrap-setup.c @@ -43,8 +43,6 @@ #include "wrap-setup.h" #include "utils.h" -#define MOCK_ABI "mock-multiarch-tuple" - /* These match the first entry in PvMultiArchdetails.platforms, * which is the easiest realistic thing for a mock implementation of * srt_system_info_check_library() to use. */ @@ -56,7 +54,25 @@ * a mock implementation of srt_system_info_check_library() to use. */ #define MOCK_LIB_32 "lib/" SRT_ABI_I386 #define MOCK_LIB_64 "lib/" SRT_ABI_X86_64 -#define MOCK_LIB_GENERIC "lib/" MOCK_ABI +#define MOCK_LIB_GENERIC "lib/" _SRT_MULTIARCH + +#if defined(__i386__) || defined(__x86_64__) + /* On x86, we treat x86_64 as the primary architecture. + * This means it's the first one whenever we have a list of + * per-architecture things, and if we pretend to only support + * one architecture for test coverage purposes, that architecture + * will be x86_64. */ +# define PRIMARY_ABI SRT_ABI_X86_64 +# define PRIMARY_PLATFORM MOCK_PLATFORM_64 +# define PRIMARY_LIB MOCK_LIB_64 +#else + /* On non-x86, the mock implementation of srt_system_info_check_library() + * uses these expansions for ${PLATFORM} and ${LIB} instead of the + * real ones. */ +# define PRIMARY_ABI _SRT_MULTIARCH +# define PRIMARY_PLATFORM MOCK_PLATFORM_GENERIC +# define PRIMARY_LIB MOCK_LIB_GENERIC +#endif typedef struct { @@ -76,6 +92,7 @@ typedef struct typedef struct { PvRuntimeFlags runtime_flags; + PvAppendPreloadFlags preload_flags; } Config; static const Config default_config = {}; @@ -88,6 +105,10 @@ static const Config interpreter_root_config = .runtime_flags = (PV_RUNTIME_FLAGS_COPY_RUNTIME | PV_RUNTIME_FLAGS_INTERPRETER_ROOT), }; +static const Config one_arch_config = +{ + .preload_flags = PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE, +}; static int open_or_die (const char *path, @@ -232,6 +253,7 @@ static void setup_ld_preload (Fixture *f, gconstpointer context) { + const Config *config = context; static const char * const touch[] = { "app/lib/libpreloadA.so", @@ -242,20 +264,28 @@ setup_ld_preload (Fixture *f, "steam/lib/gameoverlayrenderer.so", "usr/lib/libpreloadU.so", "usr/local/lib/libgtk3-nocsd.so.0", + "opt/" PRIMARY_LIB "/libpreloadL.so", + "platform/plat-" PRIMARY_PLATFORM "/libpreloadP.so", + }; #if defined(__i386__) || defined(__x86_64__) + static const char * const touch_i386[] = + { "opt/" MOCK_LIB_32 "/libpreloadL.so", - "opt/" MOCK_LIB_64 "/libpreloadL.so", "platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so", - "platform/plat-" MOCK_PLATFORM_64 "/libpreloadP.so", "in-root-plat-" MOCK_PLATFORM_32 "-only-32-bit.so", -#else - "opt/" MOCK_LIB_GENERIC "/libpreloadL.so", - "platform/plat-" MOCK_PLATFORM_GENERIC "/libpreloadP.so", -#endif }; +#endif setup (f, context); fixture_populate_dir (f, f->mock_host->fd, touch, G_N_ELEMENTS (touch)); + + if (!(config->preload_flags & PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE)) + { +#if defined(__i386__) || defined(__x86_64__) + fixture_populate_dir (f, f->mock_host->fd, touch_i386, G_N_ELEMENTS (touch_i386)); +#endif + } + f->env = g_environ_setenv (f->env, "STEAM_COMPAT_CLIENT_INSTALL_PATH", "/steam", TRUE); } @@ -949,37 +979,37 @@ test_options_true (Fixture *f, g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_AUDIT); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT); g_assert_cmpstr (module->preload, ==, "libaudit.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_AUDIT); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT); g_assert_cmpstr (module->preload, ==, "libaudit1.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_AUDIT); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_AUDIT); g_assert_cmpstr (module->preload, ==, "libaudit2.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_PRELOAD); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD); g_assert_cmpstr (module->preload, ==, "libpreload.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_PRELOAD); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD); g_assert_cmpstr (module->preload, ==, "libpreload1.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_PRELOAD); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD); g_assert_cmpstr (module->preload, ==, "libpreload2.so"); g_assert_cmpuint (options->preload_modules->len, >, i); module = &g_array_index (options->preload_modules, WrapPreloadModule, i++); - g_assert_cmpint (module->which, ==, PRELOAD_VARIABLE_INDEX_LD_PRELOAD); + g_assert_cmpint (module->which, ==, PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD); g_assert_cmpstr (module->preload, ==, "libpreload3.so"); g_assert_cmpuint (i, ==, options->preload_modules->len); @@ -1582,8 +1612,7 @@ populate_ld_preload (Fixture *f, } pv_wrap_append_preload (argv, - "LD_PRELOAD", - "--ld-preload", + PV_PRELOAD_VARIABLE_INDEX_LD_PRELOAD, preloads[i].string, f->env, flags | PV_APPEND_PRELOAD_FLAGS_IN_UNIT_TESTS, @@ -1608,68 +1637,95 @@ populate_ld_preload (Fixture *f, static const char * const expected_preload_paths[] = { "/app/lib/libpreloadA.so", -#if defined(__i386__) || defined(__x86_64__) - "/platform/plat-" MOCK_PLATFORM_64 "/libpreloadP.so:abi=" SRT_ABI_X86_64, - "/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so:abi=" SRT_ABI_I386, - "/opt/" MOCK_LIB_64 "/libpreloadL.so:abi=" SRT_ABI_X86_64, - "/opt/" MOCK_LIB_32 "/libpreloadL.so:abi=" SRT_ABI_I386, -#else - "/platform/plat-" MOCK_PLATFORM_GENERIC "/libpreloadP.so:abi=" MOCK_ABI, - "/opt/" MOCK_LIB_GENERIC "/libpreloadL.so:abi=" MOCK_ABI, -#endif + "/platform/plat-" PRIMARY_PLATFORM "/libpreloadP.so:abi=" PRIMARY_ABI, + "i386:/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so:abi=" SRT_ABI_I386, + "/opt/" PRIMARY_LIB "/libpreloadL.so:abi=" PRIMARY_ABI, + "i386:/opt/" MOCK_LIB_32 "/libpreloadL.so:abi=" SRT_ABI_I386, "/lib/libpreload-rootfs.so", "/usr/lib/libpreloadU.so", "/home/me/libpreloadH.so", "/steam/lib/gameoverlayrenderer.so", "/overlay/libs/${ORIGIN}/../lib/libpreloadO.so", "/future/libs-$FUTURE/libpreloadF.so", -#if defined(__i386__) || defined(__x86_64__) - "/in-root-plat-i686-only-32-bit.so:abi=" SRT_ABI_I386, -#endif + "i386:/in-root-plat-i686-only-32-bit.so:abi=" SRT_ABI_I386, "/in-root-${FUTURE}.so", "./${RELATIVE}.so", "./relative.so", /* Our mock implementation of pv_runtime_has_library() behaves as though * libfakeroot is not in the runtime or graphics stack provider, only * the current namespace */ -#if defined(__i386__) || defined(__x86_64__) - "/path/to/" MOCK_LIB_64 "/libfakeroot.so:abi=" SRT_ABI_X86_64, - "/path/to/" MOCK_LIB_32 "/libfakeroot.so:abi=" SRT_ABI_I386, -#else - "/path/to/" MOCK_LIB_GENERIC "/libfakeroot.so:abi=" MOCK_ABI, -#endif + "/path/to/" PRIMARY_LIB "/libfakeroot.so:abi=" PRIMARY_ABI, + "i386:/path/to/" MOCK_LIB_32 "/libfakeroot.so:abi=" SRT_ABI_I386, /* Our mock implementation of pv_runtime_has_library() behaves as though * libpthread.so.0 *is* in the runtime, as we would expect */ "libpthread.so.0", }; +static GPtrArray * +filter_expected_paths (const Config *config) +{ + g_autoptr(GPtrArray) filtered = g_ptr_array_new_with_free_func (NULL); + gsize i; + + /* Some of the expected paths are only expected to appear on i386. + * Filter the list accordingly. */ + for (i = 0; i < G_N_ELEMENTS (expected_preload_paths); i++) + { + const char *path = expected_preload_paths[i]; + + if (g_str_has_prefix (path, "i386:")) + { +#if defined(__i386__) || defined(__x86_64__) + if (!(config->preload_flags & PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE)) + g_ptr_array_add (filtered, (char *) (path + strlen ("i386:"))); +#endif + } + else + { + g_ptr_array_add (filtered, (char *) path); + } + } + + return g_steal_pointer (&filtered); +} + static void test_remap_ld_preload (Fixture *f, gconstpointer context) { + const Config *config = context; g_autoptr(FlatpakExports) exports = fixture_create_exports (f); g_autoptr(GPtrArray) argv = g_ptr_array_new_with_free_func (g_free); + g_autoptr(GPtrArray) filtered = filter_expected_paths (config); g_autoptr(PvRuntime) runtime = fixture_create_runtime (f, PV_RUNTIME_FLAGS_NONE); gsize i; + gboolean expect_i386 = FALSE; - populate_ld_preload (f, argv, PV_APPEND_PRELOAD_FLAGS_NONE, runtime, exports); +#if defined(__i386__) || defined(__x86_64__) + if (!(config->preload_flags & PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE)) + expect_i386 = TRUE; +#endif - g_assert_cmpuint (argv->len, ==, G_N_ELEMENTS (expected_preload_paths)); + populate_ld_preload (f, argv, config->preload_flags, runtime, exports); + + g_assert_cmpuint (argv->len, ==, filtered->len); for (i = 0; i < argv->len; i++) { + char *expected = g_ptr_array_index (filtered, i); char *argument = g_ptr_array_index (argv, i); + g_assert_true (g_str_has_prefix (argument, "--ld-preload=")); argument += strlen("--ld-preload="); - if (g_str_has_prefix (expected_preload_paths[i], "/lib/") - || g_str_has_prefix (expected_preload_paths[i], "/usr/lib/")) + if (g_str_has_prefix (expected, "/lib/") + || g_str_has_prefix (expected, "/usr/lib/")) { g_assert_true (g_str_has_prefix (argument, "/run/host/")); argument += strlen("/run/host"); } - g_assert_cmpstr (argument, ==, expected_preload_paths[i]); + g_assert_cmpstr (argument, ==, expected); } /* FlatpakExports never exports /app */ @@ -1688,15 +1744,12 @@ test_remap_ld_preload (Fixture *f, g_assert_false (flatpak_exports_path_is_visible (exports, "/opt")); g_assert_false (flatpak_exports_path_is_visible (exports, "/opt/lib")); g_assert_false (flatpak_exports_path_is_visible (exports, "/platform")); -#if defined(__i386__) || defined(__x86_64__) - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_32 "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_64 "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_64 "/libpreloadP.so")); -#else - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_GENERIC "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_GENERIC "/libpreloadP.so")); -#endif + + g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" PRIMARY_LIB "/libpreloadL.so")); + g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" PRIMARY_PLATFORM "/libpreloadP.so")); + + g_assert_cmpint (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_32 "/libpreloadL.so"), ==, expect_i386); + g_assert_cmpint (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so"), ==, expect_i386); /* FlatpakExports never exports /lib as /lib */ g_assert_false (flatpak_exports_path_is_visible (exports, "/lib")); @@ -1730,30 +1783,36 @@ static void test_remap_ld_preload_flatpak (Fixture *f, gconstpointer context) { + const Config *config = context; g_autoptr(GPtrArray) argv = g_ptr_array_new_with_free_func (g_free); + g_autoptr(GPtrArray) filtered = filter_expected_paths (config); g_autoptr(PvRuntime) runtime = fixture_create_runtime (f, PV_RUNTIME_FLAGS_FLATPAK_SUBSANDBOX); gsize i; - populate_ld_preload (f, argv, PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX, + populate_ld_preload (f, argv, + (config->preload_flags + | PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX), runtime, NULL); - g_assert_cmpuint (argv->len, ==, G_N_ELEMENTS (expected_preload_paths)); + g_assert_cmpuint (argv->len, ==, filtered->len); for (i = 0; i < argv->len; i++) { + char *expected = g_ptr_array_index (filtered, i); char *argument = g_ptr_array_index (argv, i); + g_assert_true (g_str_has_prefix (argument, "--ld-preload=")); argument += strlen("--ld-preload="); - if (g_str_has_prefix (expected_preload_paths[i], "/app/") - || g_str_has_prefix (expected_preload_paths[i], "/lib/") - || g_str_has_prefix (expected_preload_paths[i], "/usr/lib/")) + if (g_str_has_prefix (expected, "/app/") + || g_str_has_prefix (expected, "/lib/") + || g_str_has_prefix (expected, "/usr/lib/")) { g_assert_true (g_str_has_prefix (argument, "/run/parent/")); argument += strlen("/run/parent"); } - g_assert_cmpstr (argument, ==, expected_preload_paths[i]); + g_assert_cmpstr (argument, ==, expected); } } @@ -1766,31 +1825,44 @@ static void test_remap_ld_preload_no_runtime (Fixture *f, gconstpointer context) { + const Config *config = context; g_autoptr(GPtrArray) argv = g_ptr_array_new_with_free_func (g_free); + g_autoptr(GPtrArray) filtered = filter_expected_paths (config); g_autoptr(FlatpakExports) exports = fixture_create_exports (f); gsize i, j; + gboolean expect_i386 = FALSE; - populate_ld_preload (f, argv, PV_APPEND_PRELOAD_FLAGS_REMOVE_GAME_OVERLAY, +#if defined(__i386__) || defined(__x86_64__) + if (!(config->preload_flags & PV_APPEND_PRELOAD_FLAGS_ONE_ARCHITECTURE)) + expect_i386 = TRUE; +#endif + + populate_ld_preload (f, argv, + (config->preload_flags + | PV_APPEND_PRELOAD_FLAGS_REMOVE_GAME_OVERLAY), NULL, exports); - g_assert_cmpuint (argv->len, ==, G_N_ELEMENTS (expected_preload_paths) - 1); + g_assert_cmpuint (argv->len, ==, filtered->len - 1); for (i = 0, j = 0; i < argv->len; i++, j++) { + char *expected = g_ptr_array_index (filtered, j); char *argument = g_ptr_array_index (argv, i); + g_assert_true (g_str_has_prefix (argument, "--ld-preload=")); argument += strlen("--ld-preload="); /* /steam/lib/gameoverlayrenderer.so is missing because we used the * REMOVE_GAME_OVERLAY flag */ - if (g_str_has_suffix (expected_preload_paths[j], "/gameoverlayrenderer.so")) + if (g_str_has_suffix (expected, "/gameoverlayrenderer.so")) { /* We expect to skip only one element */ g_assert_cmpint (i, ==, j); j++; + expected = g_ptr_array_index (filtered, j); } - g_assert_cmpstr (argument, ==, expected_preload_paths[j]); + g_assert_cmpstr (argument, ==, expected); } /* FlatpakExports never exports /app */ @@ -1809,15 +1881,12 @@ test_remap_ld_preload_no_runtime (Fixture *f, g_assert_false (flatpak_exports_path_is_visible (exports, "/opt")); g_assert_false (flatpak_exports_path_is_visible (exports, "/opt/lib")); g_assert_false (flatpak_exports_path_is_visible (exports, "/platform")); -#if defined(__i386__) || defined(__x86_64__) - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_32 "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_64 "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_64 "/libpreloadP.so")); -#else - g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_GENERIC "/libpreloadL.so")); - g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_GENERIC "/libpreloadP.so")); -#endif + + g_assert_true (flatpak_exports_path_is_visible (exports, "/opt/" PRIMARY_LIB "/libpreloadL.so")); + g_assert_true (flatpak_exports_path_is_visible (exports, "/platform/plat-" PRIMARY_PLATFORM "/libpreloadP.so")); + + g_assert_cmpint (flatpak_exports_path_is_visible (exports, "/opt/" MOCK_LIB_32 "/libpreloadL.so"), ==, expect_i386); + g_assert_cmpint (flatpak_exports_path_is_visible (exports, "/platform/plat-" MOCK_PLATFORM_32 "/libpreloadP.so"), ==, expect_i386); /* FlatpakExports never exports /lib as /lib */ g_assert_false (flatpak_exports_path_is_visible (exports, "/lib")); @@ -1846,21 +1915,27 @@ static void test_remap_ld_preload_flatpak_no_runtime (Fixture *f, gconstpointer context) { + const Config *config = context; g_autoptr(GPtrArray) argv = g_ptr_array_new_with_free_func (g_free); + g_autoptr(GPtrArray) filtered = filter_expected_paths (config); gsize i; - populate_ld_preload (f, argv, PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX, + populate_ld_preload (f, argv, + (config->preload_flags + | PV_APPEND_PRELOAD_FLAGS_FLATPAK_SUBSANDBOX), NULL, NULL); - g_assert_cmpuint (argv->len, ==, G_N_ELEMENTS (expected_preload_paths)); + g_assert_cmpuint (argv->len, ==, filtered->len); for (i = 0; i < argv->len; i++) { + char *expected = g_ptr_array_index (filtered, i); char *argument = g_ptr_array_index (argv, i); + g_assert_true (g_str_has_prefix (argument, "--ld-preload=")); argument += strlen("--ld-preload="); - g_assert_cmpstr (argument, ==, expected_preload_paths[i]); + g_assert_cmpstr (argument, ==, expected); } } @@ -1911,6 +1986,7 @@ test_supported_archs (Fixture *f, /* The array of tuples has one extra element, to make it a GStrv */ g_assert_cmpstr (pv_multiarch_tuples[i], ==, NULL); +#if PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST > 0 /* Emulator host details and tuples are also in the same order */ for (i = 0; i < PV_N_SUPPORTED_ARCHITECTURES_AS_EMULATOR_HOST; i++) { @@ -1918,6 +1994,9 @@ test_supported_archs (Fixture *f, g_assert_cmpstr (pv_multiarch_as_emulator_tuples[i], ==, details->tuple); } +#else + i = 0; +#endif /* Array of tuples has one extra element, again */ g_assert_cmpstr (pv_multiarch_as_emulator_tuples[i], ==, NULL); @@ -2228,13 +2307,13 @@ main (int argc, g_test_add ("/options/true", Fixture, NULL, setup, test_options_true, teardown); g_test_add ("/passwd", Fixture, NULL, setup, test_passwd, teardown); - g_test_add ("/remap-ld-preload", Fixture, NULL, + g_test_add ("/remap-ld-preload", Fixture, &default_config, setup_ld_preload, test_remap_ld_preload, teardown); - g_test_add ("/remap-ld-preload-flatpak", Fixture, NULL, + g_test_add ("/remap-ld-preload-flatpak", Fixture, &default_config, setup_ld_preload, test_remap_ld_preload_flatpak, teardown); - g_test_add ("/remap-ld-preload-no-runtime", Fixture, NULL, + g_test_add ("/remap-ld-preload-no-runtime", Fixture, &default_config, setup_ld_preload, test_remap_ld_preload_no_runtime, teardown); - g_test_add ("/remap-ld-preload-flatpak-no-runtime", Fixture, NULL, + g_test_add ("/remap-ld-preload-flatpak-no-runtime", Fixture, &default_config, setup_ld_preload, test_remap_ld_preload_flatpak_no_runtime, teardown); g_test_add ("/supported-archs", Fixture, NULL, setup, test_supported_archs, teardown); @@ -2243,5 +2322,14 @@ main (int argc, g_test_add ("/use-host-os", Fixture, NULL, setup, test_use_host_os, teardown); + g_test_add ("/one-arch/remap-ld-preload", Fixture, &one_arch_config, + setup_ld_preload, test_remap_ld_preload, teardown); + g_test_add ("/one-arch/remap-ld-preload-flatpak", Fixture, &one_arch_config, + setup_ld_preload, test_remap_ld_preload_flatpak, teardown); + g_test_add ("/one-arch/remap-ld-preload-no-runtime", Fixture, &one_arch_config, + setup_ld_preload, test_remap_ld_preload_no_runtime, teardown); + g_test_add ("/one-arch/remap-ld-preload-flatpak-no-runtime", Fixture, &one_arch_config, + setup_ld_preload, test_remap_ld_preload_flatpak_no_runtime, teardown); + return g_test_run (); } diff --git a/tests/system-info.c b/tests/system-info.c index 0dac96383fe7b66f8bacd646caa1f450fcad699f..1c5a8e21b641e526df67b80613a60d46aeaf70f2 100644 --- a/tests/system-info.c +++ b/tests/system-info.c @@ -2119,6 +2119,28 @@ os_no_os_release (Fixture *f, g_free (sysroot); } +#ifdef _SRT_TESTS_STRICT +static void +os_real (Fixture *f, + gconstpointer context) +{ + g_autoptr(SrtSystemInfo) info = NULL; + gchar *s; + + info = srt_system_info_new (NULL); + check_os_release (info); + + /* We expect the ID and NAME to be present on any reasonable OS. */ + s = srt_system_info_dup_os_id (info); + g_assert_cmpstr (s, !=, NULL); + g_free (s); + + s = srt_system_info_dup_os_name (info); + g_assert_cmpstr (s, !=, NULL); + g_free (s); +} +#endif + static void overrides (Fixture *f, gconstpointer context) @@ -4505,6 +4527,10 @@ main (int argc, setup, os_invalid_os_release, teardown); g_test_add ("/system-info/os/no-os-release", Fixture, NULL, setup, os_no_os_release, teardown); +#ifdef _SRT_TESTS_STRICT + g_test_add ("/system-info/os/real", Fixture, NULL, + setup, os_real, teardown); +#endif g_test_add ("/system-info/libs/overrides", Fixture, NULL, setup, overrides, teardown); diff --git a/tests/utils.c b/tests/utils.c index a70beed3320615a71701e62b465e9d77c01ed5f4..8fbb2e9138b5e9fdd02dfff0c6aca8901fe6d713 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -1434,6 +1434,11 @@ test_recursive_list (Fixture *f, } else { +#ifdef _SRT_TESTS_STRICT + /* We expect this to exist in our official CI, + * so make the test fail if it doesn't. */ + g_warning ("/dev/pts doesn't exist or isn't a directory"); +#endif /* This could conceivably be false in some containers. * Mark the test as skipped but intentionally don't early-return * here: we can still check for /dev/stderr. */ @@ -1450,6 +1455,11 @@ test_recursive_list (Fixture *f, } else { +#ifdef _SRT_TESTS_STRICT + /* We expect this to exist in our official CI, + * so make the test fail if it doesn't. */ + g_warning ("/dev/stderr isn't a symlink"); +#endif /* This could conceivably be false in some containers. * Again, intentionally not early-returning here. */ g_test_skip ("/dev/stderr isn't a symlink"); @@ -1578,6 +1588,7 @@ static const struct { { "", 0, "", TRUE }, { "bar", -1, "bar", TRUE }, + { "bar", -1, "bard", FALSE }, { "foobar", -1, "bar", TRUE }, { "foobar", -1, "BAR", FALSE }, { "foo\0bar", 7, "ar", TRUE },