From 561629f9a4398f9faea4466868a3a4ba8a367481 Mon Sep 17 00:00:00 2001 From: Ludovico de Nittis <ludovico.denittis@collabora.com> Date: Wed, 21 Apr 2021 16:37:00 +0200 Subject: [PATCH] tests: Add coverage for the dynamic linker expansions Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com> --- tests/meson.build | 19 ++++++ tests/mock-bad-detect.c | 45 +++++++++++++ tests/mock-good-detect.c | 43 ++++++++++++ tests/system-info.c | 141 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 248 insertions(+) create mode 100644 tests/mock-bad-detect.c create mode 100644 tests/mock-good-detect.c diff --git a/tests/meson.build b/tests/meson.build index ce0955bf3..59b035546 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -287,6 +287,25 @@ foreach helper : [ ) endforeach +foreach token : [ + 'LIB', + 'PLATFORM', +] + foreach helper : [ + 'mock-good-detect', + 'mock-bad-detect', + ] + executable( + helper + '-' + token.to_lower(), + helper + '.c', + c_args : ['-DMOCK_LIBDL_TOKEN_' + token], + include_directories : project_include_dirs, + install: true, + install_dir: tests_dir + ) + endforeach +endforeach + # These need to be the same as their -good- counterparts, to exercise # the case where the preliminary check succeeds, but actually rendering # a window fails (hence "mixed"). diff --git a/tests/mock-bad-detect.c b/tests/mock-bad-detect.c new file mode 100644 index 000000000..556f4987e --- /dev/null +++ b/tests/mock-bad-detect.c @@ -0,0 +1,45 @@ +/* + * Copyright © 2021 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * 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 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 <stdio.h> + +int +main (int argc, + char **argv) +{ + +#if defined(MOCK_LIBDL_TOKEN_PLATFORM) + const char *output = "Unable to find the library: ${ORIGIN}/i386-linux-gnu/${PLATFORM}/libidentify-platform.so: " + "cannot open shared object file: No such file or directory"; +#else + const char *output = "Unable to find the library: ${ORIGIN}/i386-linux-gnu/${PLATFORM}/libidentify-lib.so: " + "cannot open shared object file: No such file or directory"; +#endif + + // Give bad output + fprintf (stderr, "%s\n", output); + return 1; +} + diff --git a/tests/mock-good-detect.c b/tests/mock-good-detect.c new file mode 100644 index 000000000..ae9b8df7b --- /dev/null +++ b/tests/mock-good-detect.c @@ -0,0 +1,43 @@ +/* + * Copyright © 2021 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * 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 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 <stdio.h> + +int +main (int argc, + char **argv) +{ + +#if defined(MOCK_LIBDL_TOKEN_PLATFORM) + const char *output = "x86_64"; +#else + const char *output = "lib"; +#endif + + // Give good output + printf ("%s\n", output); + return 0; +} + diff --git a/tests/system-info.c b/tests/system-info.c index 47b377d4a..ca964d7ff 100644 --- a/tests/system-info.c +++ b/tests/system-info.c @@ -165,6 +165,53 @@ test_object (Fixture *f, g_object_unref (info); } +static void +test_libdl (Fixture *f, + gconstpointer context) +{ + g_autoptr(SrtSystemInfo) info = NULL; + g_autofree gchar *libdl = NULL; + g_autoptr(GError) error = NULL; + + info = srt_system_info_new (NULL); + g_assert_nonnull (info); + srt_system_info_set_helpers_path (info, f->builddir); + libdl = srt_system_info_dup_libdl_lib (info, "mock-good", &error); + g_assert_cmpstr (libdl, ==, "lib"); + g_assert_no_error (error); + g_free (libdl); + /* Test cache */ + libdl = srt_system_info_dup_libdl_lib (info, "mock-good", &error); + g_assert_cmpstr (libdl, ==, "lib"); + g_assert_no_error (error); + g_free (libdl); + + libdl = srt_system_info_dup_libdl_platform (info, "mock-good", &error); + g_assert_cmpstr (libdl, ==, "x86_64"); + g_assert_no_error (error); + g_free (libdl); + /* Test cache */ + libdl = srt_system_info_dup_libdl_platform (info, "mock-good", &error); + g_assert_cmpstr (libdl, ==, "x86_64"); + g_assert_no_error (error); + g_free (libdl); + + libdl = srt_system_info_dup_libdl_lib (info, "mock-bad", &error); + g_assert_cmpstr (libdl, ==, NULL); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_cmpstr (error->message, ==, "Unable to find the library: " + "${ORIGIN}/i386-linux-gnu/${PLATFORM}/libidentify-lib.so: " + "cannot open shared object file: No such file or directory\n"); + + g_clear_error (&error); + libdl = srt_system_info_dup_libdl_platform (info, "mock-bad", &error); + g_assert_cmpstr (libdl, ==, NULL); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_cmpstr (error->message, ==, "Unable to find the library: " + "${ORIGIN}/i386-linux-gnu/${PLATFORM}/libidentify-platform.so: " + "cannot open shared object file: No such file or directory\n"); +} + static void check_libraries_result (GList *libraries) { @@ -2440,6 +2487,13 @@ assert_equal_strings_arrays (const gchar * const *array1, static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64 }; +typedef enum +{ + LIBDL_TOKEN_SKIP = 0, + LIBDL_TOKEN_LIB, + LIBDL_TOKEN_PLATFORM, +} LibdlToken; + typedef struct { const gchar *path; @@ -2519,9 +2573,19 @@ typedef struct const char *error_message; } RuntimeLinkerTest; +typedef struct +{ + LibdlToken libdl_token; + const char *expansion_value; + const char *error_domain; + int error_code; + const char *error_message; +} LibdlTest; + typedef struct { gboolean can_run; + LibdlTest libdl[3]; SrtLibraryIssues issues; RuntimeLinkerTest runtime_linker; DriverTest dri_drivers[5]; @@ -2670,6 +2734,20 @@ static const JsonTest json_test[] = { { .can_run = FALSE, + .libdl = + { + { + .libdl_token = LIBDL_TOKEN_LIB, + .expansion_value = "lib32", + }, + { + .libdl_token = LIBDL_TOKEN_PLATFORM, + .error_domain = "g-io-error-quark", + .error_code = G_IO_ERROR_NOT_FOUND, + .error_message = "Unable to find the library: ${ORIGIN}/i386-linux-gnu/${PLATFORM}/libidentify-platform.so: " + "cannot open shared object file: No such file or directory", + }, + }, .runtime_linker = { .path = "/lib/ld-linux.so.2", @@ -2762,6 +2840,17 @@ static const JsonTest json_test[] = { .can_run = TRUE, + .libdl = + { + { + .libdl_token = LIBDL_TOKEN_LIB, + .expansion_value = "lib", + }, + { + .libdl_token = LIBDL_TOKEN_PLATFORM, + .expansion_value = "x86_64", + }, + }, .runtime_linker = { .path = "/lib64/ld-linux-x86-64.so.2", @@ -3341,6 +3430,53 @@ assert_expected_runtime_linker (SrtSystemInfo *info, } } +static void +assert_expected_libdl (SrtSystemInfo *info, + const char *multiarch_tuple, + const LibdlTest *libdl) +{ + g_autoptr(GError) error = NULL; + g_autofree gchar *libdl_expanded = NULL; + + switch (libdl->libdl_token) + { + case LIBDL_TOKEN_LIB: + libdl_expanded = srt_system_info_dup_libdl_lib (info, multiarch_tuple, + &error); + break; + + case LIBDL_TOKEN_PLATFORM: + libdl_expanded = srt_system_info_dup_libdl_platform (info, multiarch_tuple, + &error); + break; + + case LIBDL_TOKEN_SKIP: + default: + g_return_if_reached (); + } + + g_assert_cmpstr (libdl->expansion_value, ==, libdl_expanded); + + if (libdl->expansion_value != NULL) + { + g_assert (libdl->error_domain == NULL); + g_assert (libdl->error_code == 0); + g_assert_cmpstr (libdl->error_message, ==, NULL); + + g_assert_no_error (error); + } + else + { + g_assert_cmpstr (libdl->expansion_value, ==, NULL); + g_assert_cmpstr (libdl->error_domain, !=, NULL); + g_assert_cmpstr (libdl->error_message, !=, NULL); + + g_assert_error (error, g_quark_from_string (libdl->error_domain), + libdl->error_code); + g_assert_cmpstr (error->message, ==, libdl->error_message); + } +} + static void json_parsing (Fixture *f, gconstpointer context) @@ -3450,6 +3586,9 @@ json_parsing (Fixture *f, g_assert_cmpint (this_arch.issues, ==, srt_system_info_check_libraries (info, multiarch_tuples[j], NULL)); + for (jj = 0; this_arch.libdl[jj].libdl_token != LIBDL_TOKEN_SKIP; jj++) + assert_expected_libdl (info, multiarch_tuples[j], &this_arch.libdl[jj]); + assert_expected_runtime_linker (info, multiarch_tuples[j], &this_arch.runtime_linker); @@ -3876,6 +4015,8 @@ main (int argc, g_test_add ("/system-info/object", Fixture, NULL, setup, test_object, teardown); + g_test_add ("/system-info/test_libdl", Fixture, NULL, + setup, test_libdl, teardown); g_test_add ("/system-info/libraries_presence", Fixture, NULL, setup, libraries_presence, teardown); g_test_add ("/system-info/auto_expectations", Fixture, NULL, -- GitLab