Skip to content
Snippets Groups Projects
Commit 86c56471 authored by Ludovico de Nittis's avatar Ludovico de Nittis
Browse files

Merge branch 'wip/denittis/T16053' into 'master'

Enhance examples/system-info.c to show libraries and uinput capabilities

See merge request steam/steam-runtime-tools!27
parents 14a78480 e5b1b980
No related branches found
No related tags found
1 merge request!27Enhance examples/system-info.c to show libraries and uinput capabilities
Pipeline #1350 passed
......@@ -24,7 +24,7 @@
executable(
'steam-runtime-system-info',
'system-info.c',
dependencies : [glib, libsteamrt_dep],
dependencies : [glib, libsteamrt_dep, json_glib],
install : true,
)
......
......@@ -27,30 +27,337 @@
* Output basic information about the system on which the tool is run.
* The output is a JSON object with the following keys:
*
* can-run:
* An object. The keys are strings representing multiarch tuples, as
* used in Debian and the freedesktop.org SDK runtime. The values are
* boolean: true if we can definitely run executables of this
* architecture, or false if we cannot prove that we can do so.
* can-write-uinput:
* The values are boolean: true if we can write to `/dev/uninput`,
* false if we are not able to do it.
*
* architectures:
* An object. The keys are multiarch tuples like %SRT_ABI_I386,
* as used in Debian and the freedesktop.org SDK runtime.
* The values are objects with more details of the architecture:
*
* can-run:
* The values are boolean: true if we can definitely run
* executables of this architecture, or false if we cannot prove
* that we can do so.
*
* library-issues-summary:
* A string array listing all the libraries problems that has been found
* in the running system. Possible values can be: "cannot-load",
* "missing-symbols", "misversioned-symbols" and "internal-error".
* If "can-run" for this architecture is false we skip the library check
* and this "library-issues-summary" will not be printed at all.
*
* library-details:
* An object. The keys are library SONAMEs, such as `libjpeg.so.62`.
* The values are objects with more details of the library:
*
* path:
* The value is a string representing the full path about where the
* @library has been found. The value is `null` if the library is
* not available in the system.
*
* issues:
* A string array listing all the @library problems that has been
* found in the running system. For possible values check
* `library-issues-summary`. This object will be available only if
* there are some issues.
*
* missing-symbols:
* A string array listing all the symbols that were expected to be
* provided by @library but were not found. This object will be
* available only if there are sone missing symbols.
*
* misversioned-symbols:
* A string array listing all the symbols that were expected to be
* provided by @library but were available with a different version.
* This object will be available only if there are some misversioned
* symbols.
*/
#include <steam-runtime-tools/steam-runtime-tools.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <glib.h>
#include <json-glib/json-glib.h>
enum
{
OPTION_HELP = 1,
OPTION_EXPECTATION,
OPTION_VERBOSE,
};
struct option long_options[] =
{
{ "expectations", required_argument, NULL, OPTION_EXPECTATION },
{ "verbose", no_argument, NULL, OPTION_VERBOSE },
{ "help", no_argument, NULL, OPTION_HELP },
{ NULL, 0, NULL, 0 }
};
static void usage (int code) __attribute__((__noreturn__));
/*
* Print usage information and exit with status @code.
*/
static void
usage (int code)
{
FILE *fp;
if (code == 0)
fp = stdout;
else
fp = stderr;
fprintf (fp, "Usage: %s [OPTIONS]\n",
program_invocation_short_name);
exit (code);
}
static FILE *
divert_stdout_to_stderr (GError **error)
{
int original_stdout_fd;
FILE *original_stdout;
/* Duplicate the original stdout so that we still have a way to write
* machine-readable output. */
original_stdout_fd = dup (STDOUT_FILENO);
if (original_stdout_fd < 0)
{
int saved_errno = errno;
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Unable to duplicate fd %d: %s",
STDOUT_FILENO, g_strerror (saved_errno));
return NULL;
}
/* If something like g_debug writes to stdout, make it come out of
* our original stderr. */
if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
{
int saved_errno = errno;
close (original_stdout_fd);
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Unable to make fd %d a copy of fd %d: %s",
STDOUT_FILENO, STDERR_FILENO, g_strerror (saved_errno));
return NULL;
}
/* original_stdout takes ownership of original_stdout_fd on success */
original_stdout = fdopen (original_stdout_fd, "w");
if (original_stdout == NULL)
{
int saved_errno = errno;
close (original_stdout_fd);
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Unable to create a stdio wrapper for fd %d: %s",
original_stdout_fd, g_strerror (saved_errno));
return NULL;
}
return original_stdout;
}
static void
jsonify_library_issues (JsonBuilder *builder,
SrtLibraryIssues issues)
{
if ((issues & SRT_LIBRARY_ISSUES_CANNOT_LOAD) != 0)
json_builder_add_string_value (builder, "cannot-load");
if ((issues & SRT_LIBRARY_ISSUES_MISSING_SYMBOLS) != 0)
json_builder_add_string_value (builder, "missing-symbols");
if ((issues & SRT_LIBRARY_ISSUES_MISVERSIONED_SYMBOLS) != 0)
json_builder_add_string_value (builder, "misversioned-symbols");
if ((issues & SRT_LIBRARY_ISSUES_INTERNAL_ERROR) != 0)
json_builder_add_string_value (builder, "internal-error");
}
static void
print_libraries_details (JsonBuilder *builder,
GList *libraries,
gboolean verbose)
{
json_builder_set_member_name (builder, "library-details");
json_builder_begin_object (builder);
for (GList *l = libraries; l != NULL; l = l->next)
{
if (verbose || srt_library_get_issues (l->data) != SRT_LIBRARY_ISSUES_NONE)
{
const char * const *missing_symbols;
const char * const *misversioned_symbols;
json_builder_set_member_name (builder, srt_library_get_soname (l->data));
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "path");
json_builder_add_string_value (builder, srt_library_get_absolute_path (l->data));
if (srt_library_get_issues (l->data) != SRT_LIBRARY_ISSUES_NONE)
{
json_builder_set_member_name (builder, "issues");
json_builder_begin_array (builder);
jsonify_library_issues (builder, srt_library_get_issues (l->data));
json_builder_end_array (builder);
}
missing_symbols = srt_library_get_missing_symbols (l->data);
if (missing_symbols[0] != NULL)
{
json_builder_set_member_name (builder, "missing-symbols");
json_builder_begin_array (builder);
for (gsize i = 0; missing_symbols[i] != NULL; i++)
json_builder_add_string_value (builder, missing_symbols[i]);
json_builder_end_array (builder);
}
misversioned_symbols = srt_library_get_misversioned_symbols (l->data);
if (misversioned_symbols[0] != NULL)
{
json_builder_set_member_name (builder, "misversioned-symbols");
json_builder_begin_array (builder);
for (gsize i = 0; misversioned_symbols[i] != NULL; i++)
json_builder_add_string_value (builder, misversioned_symbols[i]);
json_builder_end_array (builder);
}
json_builder_end_object (builder);
}
}
json_builder_end_object (builder);
return;
}
int
main (int argc,
char **argv)
{
g_print ("{\n");
FILE *original_stdout = NULL;
GError *error = NULL;
SrtSystemInfo *info;
SrtLibraryIssues issues = SRT_LIBRARY_ISSUES_NONE;
char *expectations = NULL;
gboolean verbose = FALSE;
JsonBuilder *builder;
JsonGenerator *generator;
gboolean can_run = FALSE;
gchar *json_output;
GList *libraries = NULL;
GList *detailed_errors = NULL;
int opt;
static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64 };
while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1)
{
switch (opt)
{
case OPTION_EXPECTATION:
expectations = optarg;
break;
case OPTION_VERBOSE:
verbose = TRUE;
break;
case OPTION_HELP:
usage (0);
break;
case '?':
default:
usage (1);
break; /* not reached */
}
}
if (optind != argc)
usage (1);
/* stdout is reserved for machine-readable output, so avoid having
* things like g_debug() pollute it. */
original_stdout = divert_stdout_to_stderr (&error);
if (original_stdout == NULL)
{
g_warning ("%s", error->message);
g_clear_error (&error);
return 1;
}
info = srt_system_info_new (expectations);
builder = json_builder_new ();
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "can-write-uinput");
json_builder_add_boolean_value (builder, srt_system_info_can_write_to_uinput (info));
json_builder_set_member_name (builder, "architectures");
json_builder_begin_object (builder);
for (gsize i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++)
{
json_builder_set_member_name (builder, multiarch_tuples[i]);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "can-run");
can_run = srt_system_info_can_run (info, multiarch_tuples[i]);
json_builder_add_boolean_value (builder, can_run);
if (can_run && expectations != NULL)
{
json_builder_set_member_name (builder, "library-issues-summary");
json_builder_begin_array (builder);
issues = srt_system_info_check_libraries (info,
multiarch_tuples[i],
&libraries);
jsonify_library_issues (builder, issues);
json_builder_end_array (builder);
}
if (libraries != NULL && (issues != SRT_LIBRARY_ISSUES_NONE || verbose))
print_libraries_details (builder, libraries, verbose);
json_builder_end_object (builder);
g_list_free_full (detailed_errors, g_free);
g_list_free_full (libraries, g_object_unref);
}
json_builder_end_object (builder);
json_builder_end_object (builder);
JsonNode *root = json_builder_get_root (builder);
generator = json_generator_new ();
json_generator_set_root (generator, root);
json_generator_set_pretty (generator, TRUE);
json_output = json_generator_to_data (generator, NULL);
if (fputs (json_output, original_stdout) < 0)
g_warning ("Unable to write output: %s", g_strerror (errno));
if (fputs ("\n", original_stdout) < 0)
g_warning ("Unable to write final newline: %s", g_strerror (errno));
if (fclose (original_stdout) != 0)
g_warning ("Unable to close stdout: %s", g_strerror (errno));
g_print (" \"can-run\": {\n");
g_print (" \"%s\": %s,\n", SRT_ABI_I386,
srt_architecture_can_run_i386 () ? "true" : "false");
g_print (" \"%s\": %s\n", SRT_ABI_X86_64,
srt_architecture_can_run_x86_64 () ? "true" : "false");
g_print (" }\n");
g_free (json_output);
g_object_unref (generator);
json_node_free (root);
g_object_unref (builder);
g_object_unref (info);
g_print ("}\n");
return 0;
}
......@@ -69,9 +69,6 @@
* [3] http://git.compiz.org/fusion/misc/compiz-manager/tree/compiz-manager
*/
/* for strcasestr */
#define _GNU_SOURCE
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
......
......@@ -23,9 +23,6 @@
* Cosimo Cecchi <cosimo@endlessm.com>
*/
/* for strcasestr */
#define _GNU_SOURCE
#include <locale.h>
#include <stdlib.h>
#include <string.h>
......
......@@ -35,9 +35,6 @@ executable(
multiarch + '-inspect-library',
'inspect-library.c',
dependencies : [libdl],
c_args : [
'-D_GNU_SOURCE',
],
install : true,
install_dir : join_paths(
get_option('libexecdir'),
......
......@@ -91,6 +91,8 @@ endforeach
add_project_arguments(['-std=c99'], language : 'c')
add_project_arguments(['-D_GNU_SOURCE'], language : 'c')
glib = dependency(
'glib-2.0',
version : '>= 2.32',
......
......@@ -56,7 +56,6 @@ libsteamrt = library(
c_args : [
'-DG_LOG_DOMAIN="' + meson.project_name() + '"',
'-D_SRT_COMPILATION',
'-D_GNU_SOURCE',
'-D_SRT_SONAME="libsteam-runtime-tools-' + api_major + '.so.' + abi_major + '"',
'-D_SRT_MULTIARCH="' + multiarch + '"',
'-D_SRT_API_MAJOR="' + api_major + '"',
......
/*
* Copyright © 2019 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 <steam-runtime-tools/steam-runtime-tools.h>
#include <steam-runtime-tools/glib-compat.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <json-glib/json-glib.h>
#include "test-utils.h"
static const char *argv0;
static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64 };
typedef struct
{
gchar *srcdir;
gchar *builddir;
} Fixture;
typedef struct
{
int unused;
} Config;
static void
setup (Fixture *f,
gconstpointer context)
{
G_GNUC_UNUSED const Config *config = context;
f->srcdir = g_strdup (g_getenv ("G_TEST_SRCDIR"));
f->builddir = g_strdup (g_getenv ("G_TEST_BUILDDIR"));
if (f->srcdir == NULL)
f->srcdir = g_path_get_dirname (argv0);
if (f->builddir == NULL)
f->builddir = g_path_get_dirname (argv0);
}
static void
teardown (Fixture *f,
gconstpointer context)
{
G_GNUC_UNUSED const Config *config = context;
g_free (f->srcdir);
g_free (f->builddir);
}
/*
* Test if the expected libraries are available in the
* running system.
*/
static void
libraries_presence (Fixture *f,
gconstpointer context)
{
int exit_status = -1;
JsonParser *parser = NULL;
JsonNode *node = NULL;
JsonObject *json;
JsonObject *json_arch;
GError *error = NULL;
gchar *output = NULL;
gchar *examples = NULL;
SrtSystemInfo *info = srt_system_info_new (NULL);
gchar *expectations_in = g_build_filename (f->srcdir, "expectations", NULL);
const gchar *argv[] =
{
"steam-runtime-system-info", "--expectations", expectations_in, NULL
};
g_assert_true (g_spawn_sync (NULL, /* working directory */
(gchar **) argv,
NULL, /* envp */
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
NULL, /* stderr */
&exit_status,
&error));
g_assert_cmpint (exit_status, ==, 0);
g_assert_null (error);
g_assert_nonnull (output);
/* We can't use `json_from_string()` directly because we are targeting an
* older json-glib version */
parser = json_parser_new ();
g_assert_true (json_parser_load_from_data (parser, output, -1, NULL));
node = json_parser_get_root (parser);
json = json_node_get_object (node);
g_assert_true (json_object_has_member (json, "can-write-uinput"));
g_assert_true (json_object_has_member (json, "architectures"));
json = json_object_get_object_member (json, "architectures");
for (gsize i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++)
{
g_assert_true (json_object_has_member (json, multiarch_tuples[i]));
json_arch = json_object_get_object_member (json, multiarch_tuples[i]);
g_assert_true (json_object_has_member (json_arch, "can-run"));
g_assert_cmpint (json_object_get_boolean_member (json_arch, "can-run"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
g_assert_cmpint (json_object_has_member (json_arch, "library-issues-summary"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
if (json_object_has_member (json_arch, "library-issues-summary"))
{
JsonArray *array;
array = json_object_get_array_member (json_arch, "library-issues-summary");
g_assert_cmpint (json_array_get_length (array), ==, 0);
}
}
g_object_unref (parser);
g_object_unref (info);
g_free (examples);
g_free (expectations_in);
g_free (output);
g_clear_error (&error);
}
static void
check_libraries_missing (JsonObject *json_arch)
{
JsonArray *array;
JsonObject *json_details;
JsonObject *json_lib;
if (json_object_has_member (json_arch, "library-issues-summary"))
{
array = json_object_get_array_member (json_arch, "library-issues-summary");
g_assert_cmpint (json_array_get_length (array), ==, 3);
g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "cannot-load");
g_assert_cmpstr (json_array_get_string_element (array, 1), ==, "missing-symbols");
g_assert_cmpstr (json_array_get_string_element (array, 2), ==, "misversioned-symbols");
g_assert_true (json_object_has_member (json_arch, "library-details"));
json_details = json_object_get_object_member (json_arch, "library-details");
g_assert_true (json_object_has_member (json_details, "libgio-MISSING-2.0.so.0"));
json_lib = json_object_get_object_member (json_details, "libgio-MISSING-2.0.so.0");
g_assert_true (json_object_has_member (json_lib, "path"));
g_assert_cmpstr (json_object_get_string_member (json_lib, "path"), ==, NULL);
g_assert_true (json_object_has_member (json_lib, "issues"));
array = json_object_get_array_member (json_lib, "issues");
g_assert_cmpint (json_array_get_length (array), ==, 1);
g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "cannot-load");
g_assert_false (json_object_has_member (json_lib, "missing-symbols"));
g_assert_false (json_object_has_member (json_lib, "misversioned-symbols"));
g_assert_true (json_object_has_member (json_details, "libz.so.1"));
json_lib = json_object_get_object_member (json_details, "libz.so.1");
g_assert_true (json_object_has_member (json_lib, "path"));
g_assert_cmpstr (json_object_get_string_member (json_lib, "path"), !=, NULL);
g_assert_true (json_object_has_member (json_lib, "issues"));
array = json_object_get_array_member (json_lib, "issues");
g_assert_cmpint (json_array_get_length (array), ==, 2);
g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "missing-symbols");
g_assert_cmpstr (json_array_get_string_element (array, 1), ==, "misversioned-symbols");
array = json_object_get_array_member (json_lib, "missing-symbols");
g_assert_cmpint (json_array_get_length (array), ==, 1);
g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "missing@NotAvailable");
array = json_object_get_array_member (json_lib, "misversioned-symbols");
g_assert_cmpint (json_array_get_length (array), ==, 1);
g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "crc32@WRONG_VERSION");
}
}
/*
* Test libraries that are either not available or with missing and
* misversioned symbols.
*/
static void
libraries_missing (Fixture *f,
gconstpointer context)
{
int exit_status = -1;
JsonParser *parser = NULL;
JsonNode *node = NULL;
JsonObject *json;
JsonObject *json_arch;
GError *error = NULL;
gchar *output = NULL;
gchar *examples = NULL;
SrtSystemInfo *info = srt_system_info_new (NULL);
gchar *expectations_in = g_build_filename (f->srcdir, "expectations_with_missings", NULL);
const gchar *argv[] =
{
"steam-runtime-system-info", "--expectations", expectations_in, NULL
};
g_assert_true (g_spawn_sync (NULL, /* working directory */
(gchar **) argv,
NULL, /* envp */
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
NULL, /* stderr */
&exit_status,
&error));
g_assert_cmpint (exit_status, ==, 0);
g_assert_null (error);
g_assert_nonnull (output);
/* We can't use `json_from_string()` directly because we are targeting an
* older json-glib version */
parser = json_parser_new ();
g_assert_true (json_parser_load_from_data (parser, output, -1, NULL));
node = json_parser_get_root (parser);
json = json_node_get_object (node);
g_assert_true (json_object_has_member (json, "can-write-uinput"));
g_assert_true (json_object_has_member (json, "architectures"));
json = json_object_get_object_member (json, "architectures");
for (gsize i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++)
{
g_assert_true (json_object_has_member (json, multiarch_tuples[i]));
json_arch = json_object_get_object_member (json, multiarch_tuples[i]);
g_assert_true (json_object_has_member (json_arch, "can-run"));
g_assert_cmpint (json_object_get_boolean_member (json_arch, "can-run"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
g_assert_cmpint (json_object_has_member (json_arch, "library-issues-summary"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
check_libraries_missing (json_arch);
}
g_object_unref (parser);
g_object_unref (info);
g_free (examples);
g_free (expectations_in);
g_free (output);
g_clear_error (&error);
}
static void
check_library_no_errors (JsonObject *json_details,
const char *library_soname)
{
JsonObject *json_lib;
g_assert_true (json_object_has_member (json_details, library_soname));
json_lib = json_object_get_object_member (json_details, library_soname);
g_assert_true (json_object_has_member (json_lib, "path"));
g_assert_cmpstr (json_object_get_string_member (json_lib, "path"), !=, NULL);
g_assert_false (json_object_has_member (json_lib, "issues"));
g_assert_false (json_object_has_member (json_lib, "missing-symbols"));
g_assert_false (json_object_has_member (json_lib, "misversioned-symbols"));
}
static void
check_libraries_verbose (JsonObject *json_arch)
{
JsonArray *array;
JsonObject *json_details;
if (json_object_has_member (json_arch, "library-issues-summary"))
{
array = json_object_get_array_member (json_arch, "library-issues-summary");
g_assert_cmpint (json_array_get_length (array), ==, 0);
g_assert_true (json_object_has_member (json_arch, "library-details"));
json_details = json_object_get_object_member (json_arch, "library-details");
check_library_no_errors (json_details, "libgio-2.0.so.0");
check_library_no_errors (json_details, "libglib-2.0.so.0");
check_library_no_errors (json_details, "libz.so.1");
}
}
/*
* Test the presence of libraries with the verbose option
*/
static void
libraries_presence_verbose (Fixture *f,
gconstpointer context)
{
int exit_status = -1;
JsonParser *parser = NULL;
JsonNode *node = NULL;
JsonObject *json;
JsonObject *json_arch;
GError *error = NULL;
gchar *output = NULL;
gchar *examples = NULL;
SrtSystemInfo *info = srt_system_info_new (NULL);
gchar *expectations_in = g_build_filename (f->srcdir, "expectations", NULL);
const gchar *argv[] =
{
"steam-runtime-system-info", "--expectations", expectations_in, "--verbose", NULL
};
g_assert_true (g_spawn_sync (NULL, /* working directory */
(gchar **) argv,
NULL, /* envp */
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
NULL, /* stderr */
&exit_status,
&error));
g_assert_cmpint (exit_status, ==, 0);
g_assert_null (error);
g_assert_nonnull (output);
/* We can't use `json_from_string()` directly because we are targeting an
* older json-glib version */
parser = json_parser_new ();
g_assert_true (json_parser_load_from_data (parser, output, -1, NULL));
node = json_parser_get_root (parser);
json = json_node_get_object (node);
g_assert_true (json_object_has_member (json, "can-write-uinput"));
g_assert_true (json_object_has_member (json, "architectures"));
json = json_object_get_object_member (json, "architectures");
for (gsize i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++)
{
g_assert_true (json_object_has_member (json, multiarch_tuples[i]));
json_arch = json_object_get_object_member (json, multiarch_tuples[i]);
g_assert_true (json_object_has_member (json_arch, "can-run"));
g_assert_cmpint (json_object_get_boolean_member (json_arch, "can-run"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
g_assert_cmpint (json_object_has_member (json_arch, "library-issues-summary"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
check_libraries_verbose (json_arch);
}
g_object_unref (parser);
g_object_unref (info);
g_free (examples);
g_free (expectations_in);
g_free (output);
g_clear_error (&error);
}
/*
* Test `steam-runtime-system-info` with no additional arguments
*/
static void
no_arguments (Fixture *f,
gconstpointer context)
{
int exit_status = -1;
JsonParser *parser = NULL;
JsonNode *node = NULL;
JsonObject *json;
JsonObject *json_arch;
GError *error = NULL;
gchar *output = NULL;
gchar *examples = NULL;
SrtSystemInfo *info = srt_system_info_new (NULL);
gchar *expectations_in = g_build_filename (f->srcdir, "expectations", NULL);
const gchar *argv[] = { "steam-runtime-system-info", NULL };
g_assert_true (g_spawn_sync (NULL, /* working directory */
(gchar **) argv,
NULL, /* envp */
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
NULL, /* stderr */
&exit_status,
&error));
g_assert_cmpint (exit_status, ==, 0);
g_assert_null (error);
g_assert_nonnull (output);
/* We can't use `json_from_string()` directly because we are targeting an
* older json-glib version */
parser = json_parser_new ();
g_assert_true (json_parser_load_from_data (parser, output, -1, NULL));
node = json_parser_get_root (parser);
json = json_node_get_object (node);
g_assert_true (json_object_has_member (json, "can-write-uinput"));
g_assert_true (json_object_has_member (json, "architectures"));
json = json_object_get_object_member (json, "architectures");
for (gsize i = 0; i < G_N_ELEMENTS (multiarch_tuples); i++)
{
g_assert_true (json_object_has_member (json, multiarch_tuples[i]));
json_arch = json_object_get_object_member (json, multiarch_tuples[i]);
g_assert_true (json_object_has_member (json_arch, "can-run"));
g_assert_cmpint (json_object_get_boolean_member (json_arch, "can-run"),
==, srt_system_info_can_run (info, multiarch_tuples[i]));
}
g_object_unref (parser);
g_object_unref (info);
g_free (examples);
g_free (expectations_in);
g_free (output);
g_clear_error (&error);
}
int
main (int argc,
char **argv)
{
argv0 = argv[0];
g_test_init (&argc, &argv, NULL);
g_test_add ("/system-info/libraries_presence", Fixture, NULL,
setup, libraries_presence, teardown);
g_test_add ("/system-info/libraries_missing", Fixture, NULL,
setup, libraries_missing, teardown);
g_test_add ("/system-info/libraries_presence_verbose", Fixture, NULL,
setup, libraries_presence_verbose, teardown);
g_test_add ("/system-info/no_arguments", Fixture, NULL,
setup, no_arguments, teardown);
return g_test_run ();
}
......@@ -25,9 +25,11 @@ test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'helpers'))
test_env.prepend('PATH', join_paths(meson.current_build_dir(), '..', 'examples'))
tests = [
'architecture',
'examples-system-info',
'library',
'system-info',
]
......@@ -53,7 +55,7 @@ foreach test_name : tests
c_args : [
'-D_SRT_MULTIARCH="' + multiarch + '"',
],
dependencies : [glib, gobject, libsteamrt_dep],
dependencies : [glib, gobject, libsteamrt_dep, json_glib],
install : get_option('installed_tests'),
install_dir : tests_dir,
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment