From 41ac7a82fb9d761b4792d53f82d3801625f5ced8 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 25 Sep 2019 17:10:17 +0100 Subject: [PATCH] Distinguish between the Steam installation (root) and data paths Until now we've been conflating these two, but Timothee Besset recently clarified their status for me. ~/.steam/steam is maintained by bin_steam.sh, aka /usr/bin/steam, in which it is referred to as STEAMDATALINK. It is the data directory containing user data (cloud-synced configuration and saves), the download cache, and the default Steam Library directory. ~/.steam/root is maintained by steam.sh, in which it is referred to as STEAMROOTLINK. It is the installation directory, containing Steam executables and libraries. As a result, they are normally the same, but can differ, in particular in two situations: * When testing a new Steam client build by running client/steam.sh, client/ gets used as the installation directory, in conjunction with the existing data directory pointed to by ~/.steam/steam. This avoids having to re-login or re-download your library of games for the new test installation. * When Debian bug #916303 was present during the initial Steam installation, the Steam client was unpacked into ~/.steam, resulting in creation of ~/.steam/steam as a real directory that cannot be replaced with a symbolic link. We effectively ended up using ~/.steam as the installation path, but with ~/.steam/steam as the data path. (The Debian steam package has since been fixed, but we cannot easily disentangle existing installations.) Signed-off-by: Simon McVittie <smcv@collabora.com> --- bin/system-info.c | 17 +++ bin/system-info.md | 31 +++++- steam-runtime-tools/steam-internal.h | 3 +- steam-runtime-tools/steam.c | 153 ++++++++++++++++++++------- steam-runtime-tools/steam.h | 28 ++++- steam-runtime-tools/system-info.c | 88 ++++++++++++--- steam-runtime-tools/system-info.h | 1 + tests/fake-home.c | 60 ++++++++--- tests/fake-home.h | 5 +- tests/system-info-cli.c | 4 +- tests/system-info.c | 93 +++++++++++----- 11 files changed, 384 insertions(+), 99 deletions(-) diff --git a/bin/system-info.c b/bin/system-info.c index b426b2831..b63cda9ba 100644 --- a/bin/system-info.c +++ b/bin/system-info.c @@ -255,6 +255,18 @@ jsonify_steam_issues (JsonBuilder *builder, if ((issues & SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK) != 0) json_builder_add_string_value (builder, "dot-steam-steam-not-symlink"); + + if ((issues & SRT_STEAM_ISSUES_CANNOT_FIND_DATA) != 0) + json_builder_add_string_value (builder, "cannot-find-data"); + + if ((issues & SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY) != 0) + json_builder_add_string_value (builder, "dot-steam-steam-not-directory"); + + if ((issues & SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK) != 0) + json_builder_add_string_value (builder, "dot-steam-root-not-symlink"); + + if ((issues & SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY) != 0) + json_builder_add_string_value (builder, "dot-steam-root-not-directory"); } static void @@ -449,6 +461,7 @@ main (int argc, gchar *json_output; gchar *version = NULL; gchar *inst_path = NULL; + gchar *data_path = NULL; gchar *rt_path = NULL; int opt; static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64 }; @@ -503,6 +516,9 @@ main (int argc, json_builder_set_member_name (builder, "path"); inst_path = srt_system_info_dup_steam_installation_path (info); json_builder_add_string_value (builder, inst_path); + json_builder_set_member_name (builder, "data_path"); + data_path = srt_system_info_dup_steam_data_path (info); + json_builder_add_string_value (builder, data_path); json_builder_set_member_name (builder, "issues"); json_builder_begin_array (builder); steam_issues = srt_system_info_get_steam_issues (info); @@ -638,6 +654,7 @@ main (int argc, g_object_unref (builder); g_object_unref (info); g_free (rt_path); + g_free (data_path); g_free (inst_path); g_free (version); diff --git a/bin/system-info.md b/bin/system-info.md index 887c29a68..cf48f45a8 100644 --- a/bin/system-info.md +++ b/bin/system-info.md @@ -40,7 +40,16 @@ keys: : An object describing the Steam installation. The keys are strings: **path** - : A string: the absolute path to the Steam installation. + : A string: the absolute path to the Steam installation, typically + containing **steam.sh** and **ubuntu12_32** among others. + This is usually the same as **data_path** but can differ under some + circumstances. + + **data_path** + : A string: the absolute path to the Steam data directory, typically + containing **appcache**, **steamapps** and **userdata** among others. + This is usually the same as **path** but can differ under some + circumstances. **issues** : An array of strings representing problems with the Steam @@ -52,9 +61,25 @@ keys: **cannot-find** : The Steam installation could not be found. + **cannot-find-data** + : The Steam data directory could not be found. + + **dot-steam-root-not-directory** + : **~/.steam/root** is not a (symbolic link to a) directory. + Steam will probably not work. + + **dot-steam-root-not-symlink** + : **~/.steam/root** is not a symbolic link to the installation + directory. Steam will probably not work. + + **dot-steam-steam-not-directory** + : **~/.steam/steam** is not a (symbolic link to a) directory. + Steam will probably not work. + **dot-steam-steam-not-symlink** - : **~/.steam/steam** is not a symbolic link, for example - due to [Debian bug #916303](https://bugs.debian.org/916303). + : **~/.steam/steam** is not a symbolic link to the data directory, + for example due to + [Debian bug #916303](https://bugs.debian.org/916303). **runtime** : An object describing the `LD_LIBRARY_PATH`-based Steam Runtime. diff --git a/steam-runtime-tools/steam-internal.h b/steam-runtime-tools/steam-internal.h index 73863cd7a..a0d07465d 100644 --- a/steam-runtime-tools/steam-internal.h +++ b/steam-runtime-tools/steam-internal.h @@ -33,5 +33,6 @@ G_GNUC_INTERNAL SrtSteamIssues _srt_steam_check (const GStrv env, - gchar **path_out, + gchar **install_path_out, + gchar **data_path_out, gchar **bin32_out); diff --git a/steam-runtime-tools/steam.c b/steam-runtime-tools/steam.c index d14291f7b..5ed75376b 100644 --- a/steam-runtime-tools/steam.c +++ b/steam-runtime-tools/steam.c @@ -49,14 +49,19 @@ /* * _srt_steam_check: * @environ: (nullable): The list of environment variables to use. - * @path_out: (out) (optional) (nullable) (type filename): + * @install_path_out: (out) (optional) (nullable) (type filename): * Used to return the absolute path to the Steam installation + * @data_path_out: (out) (optional) (nullable) (type filename): + * Used to return the absolute path to the Steam data directory, + * which is usually the same as @install_path_out, but may be different + * while testing a new Steam release * @bin32_out: (out) (optional) (nullable) (type filename): * Used to return the absolute path to `ubuntu12_32` */ SrtSteamIssues _srt_steam_check (const GStrv environ, - gchar **path_out, + gchar **install_path_out, + gchar **data_path_out, gchar **bin32_out) { SrtSteamIssues issues = SRT_STEAM_ISSUES_NONE; @@ -64,7 +69,8 @@ _srt_steam_check (const GStrv environ, gchar *dot_steam_steam = NULL; gchar *dot_steam_root = NULL; gchar *default_steam_path = NULL; - char *path = NULL; + char *install_path = NULL; + char *data_path = NULL; char *bin32 = NULL; const char *home = NULL; const char *user_data = NULL; @@ -72,7 +78,9 @@ _srt_steam_check (const GStrv environ, g_return_val_if_fail (_srt_check_not_setuid (), SRT_STEAM_ISSUES_INTERNAL_ERROR); - g_return_val_if_fail (path_out == NULL || *path_out == NULL, + g_return_val_if_fail (install_path_out == NULL || *install_path_out == NULL, + SRT_STEAM_ISSUES_INTERNAL_ERROR); + g_return_val_if_fail (data_path_out == NULL || *data_path_out == NULL, SRT_STEAM_ISSUES_INTERNAL_ERROR); g_return_val_if_fail (bin32_out == NULL || *bin32_out == NULL, SRT_STEAM_ISSUES_INTERNAL_ERROR); @@ -95,14 +103,27 @@ _srt_steam_check (const GStrv environ, dot_steam_steam = g_build_filename (home, ".steam", "steam", NULL); dot_steam_root = g_build_filename (home, ".steam", "root", NULL); - /* Canonically, ~/.steam/steam is a symlink to the Steam installation. + /* Canonically, ~/.steam/steam is a symlink to the Steam data directory. + * This is used to install games, for example. It is *not* used to + * install the Steam client itself. + * * (This is ignoring the Valve-internal "beta universe", which uses - * ~/.steam/steambeta instead.) */ + * ~/.steam/steambeta instead, and is not open to the public.) */ if (g_file_test (dot_steam_steam, G_FILE_TEST_IS_SYMLINK)) { - path = realpath (dot_steam_steam, NULL); + data_path = realpath (dot_steam_steam, NULL); - if (path == NULL) + if (data_path == NULL) + g_debug ("realpath(%s): %s", dot_steam_steam, g_strerror (errno)); + } + else if (g_file_test (dot_steam_steam, G_FILE_TEST_IS_DIR)) + { + /* e.g. https://bugs.debian.org/916303 */ + issues |= SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK; + + data_path = realpath (dot_steam_steam, NULL); + + if (data_path == NULL) g_debug ("realpath(%s): %s", dot_steam_steam, g_strerror (errno)); } else @@ -111,20 +132,32 @@ _srt_steam_check (const GStrv environ, issues |= SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK; } - /* If that doesn't work, try ~/.steam/root, which points to whichever - * one of the public or beta universe was run most recently. */ - if (path == NULL && - g_file_test (dot_steam_root, G_FILE_TEST_IS_SYMLINK)) + if (data_path == NULL + || !g_file_test (data_path, G_FILE_TEST_IS_DIR)) + issues |= SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY; + + /* Canonically, ~/.steam/root is a symlink to the Steam installation. + * This is *usually* the same thing as the Steam data directory, but + * it can be different when testing a new Steam client build. */ + if (g_file_test (dot_steam_root, G_FILE_TEST_IS_SYMLINK)) { - path = realpath (dot_steam_root, NULL); + install_path = realpath (dot_steam_root, NULL); - if (path == NULL) + if (install_path == NULL) g_debug ("realpath(%s): %s", dot_steam_root, g_strerror (errno)); } + else + { + issues |= SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK; + } + + if (install_path == NULL + || !g_file_test (install_path, G_FILE_TEST_IS_DIR)) + issues |= SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY; - /* If *that* doesn't work, try going up one level from ubuntu12_32, - * to which ~/.steam/bin32 is a symlink */ - if (path == NULL && + /* If ~/.steam/root doesn't work, try going up one level from + * ubuntu12_32, to which ~/.steam/bin32 is a symlink */ + if (install_path == NULL && g_file_test (dot_steam_bin32, G_FILE_TEST_IS_SYMLINK)) { bin32 = realpath (dot_steam_bin32, NULL); @@ -140,61 +173,103 @@ _srt_steam_check (const GStrv environ, } else { - path = strndup (bin32, strlen (bin32) - strlen ("/ubuntu12_32")); + install_path = strndup (bin32, strlen (bin32) - strlen ("/ubuntu12_32")); /* We don't try to survive out-of-memory */ - if (path == NULL) + if (install_path == NULL) g_error ("strndup: %s", g_strerror (errno)); } } + /* If we have an installation path but no data path, or vice versa, + * assume they match. */ + if (install_path == NULL && data_path != NULL) + { + install_path = strdup (data_path); + + /* We don't try to survive out-of-memory */ + if (install_path == NULL) + g_error ("strdup: %s", g_strerror (errno)); + } + + if (data_path == NULL && install_path != NULL) + { + data_path = strdup (install_path); + + /* We don't try to survive out-of-memory */ + if (data_path == NULL) + g_error ("strdup: %s", g_strerror (errno)); + } + /* If *that* doesn't work, try the default installation location. */ - if (path == NULL) + if (install_path == NULL) { - path = realpath (default_steam_path, NULL); + install_path = realpath (default_steam_path, NULL); - if (path == NULL) + if (install_path == NULL) g_debug ("realpath(%s): %s", default_steam_path, g_strerror (errno)); } - if (path == NULL) + if (data_path == NULL) + { + data_path = realpath (default_steam_path, NULL); + + if (data_path == NULL) + g_debug ("realpath(%s): %s", default_steam_path, g_strerror (errno)); + } + + if (install_path == NULL) { g_debug ("Unable to find Steam installation"); issues |= SRT_STEAM_ISSUES_CANNOT_FIND; - goto out; } + else + { + g_debug ("Found Steam installation at %s", install_path); - g_debug ("Found Steam installation at %s", path); + /* If we haven't found ubuntu12_32 yet, it's a subdirectory of the + * Steam installation */ + if (bin32 == NULL) + { + /* We don't try to survive out-of-memory */ + if (asprintf (&bin32, "%s/ubuntu12_32", install_path) < 0) + g_error ("asprintf: %s", g_strerror (errno)); + } - /* If we haven't found ubuntu12_32 yet, it's a subdirectory of the - * Steam installation */ - if (bin32 == NULL) - { - /* We don't try to survive out-of-memory */ - if (asprintf (&bin32, "%s/ubuntu12_32", path) < 0) - g_error ("asprintf: %s", g_strerror (errno)); + if (bin32 != NULL) + { + g_debug ("Found ubuntu12_32 directory at %s", bin32); + } + else + { + g_debug ("Unable to find ubuntu12_32 directory"); + } } - if (bin32 != NULL) + if (data_path == NULL) { - g_debug ("Found ubuntu12_32 directory at %s", bin32); + g_debug ("Unable to find Steam data"); + issues |= SRT_STEAM_ISSUES_CANNOT_FIND_DATA; } else { - g_debug ("Unable to find ubuntu12_32 directory"); + g_debug ("Found Steam data at %s", data_path); } /* We can't just transfer ownership here, because in the older GLib * that we're targeting, g_free() and free() are not guaranteed to be * associated with the same memory pool. */ - if (path_out != NULL) - *path_out = g_strdup (path); + if (install_path_out != NULL) + *install_path_out = g_strdup (install_path); + + if (data_path_out != NULL) + *data_path_out = g_strdup (data_path); if (bin32_out != NULL) *bin32_out = g_strdup (bin32); -out: - free (path); + free (install_path); + free (data_path); free (bin32); g_free (dot_steam_bin32); g_free (dot_steam_steam); diff --git a/steam-runtime-tools/steam.h b/steam-runtime-tools/steam.h index 68e64c200..b19b1197e 100644 --- a/steam-runtime-tools/steam.h +++ b/steam-runtime-tools/steam.h @@ -34,10 +34,28 @@ * @SRT_STEAM_ISSUES_NONE: There are no problems * @SRT_STEAM_ISSUES_INTERNAL_ERROR: Unable to detect the status of the * Steam installation - * @SRT_STEAM_ISSUES_CANNOT_FIND: Unable to find the Steam installation + * @SRT_STEAM_ISSUES_CANNOT_FIND: Unable to find the Steam installation, + * either via its canonical symlink `~/.steam/root` or various fallback + * methods. See srt_system_info_dup_steam_installation_path(). * @SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK: `~/.steam/steam` is not - * a symbolic link to a Steam installation, which for example can happen - * if Steam was installed on a system with https://bugs.debian.org/916303 + * a symbolic link to Steam data, which for example can happen + * if Steam was installed on a system with <https://bugs.debian.org/916303>. + * See srt_system_info_dup_steam_data_path(). + * @SRT_STEAM_ISSUES_CANNOT_FIND_DATA: Unable to find the Steam data, + * either via its canonical symlink `~/.steam/steam` or various fallback + * methods. Steam is unlikely to work in this situation. + * See srt_system_info_dup_steam_data_path(). + * @SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY: `~/.steam/steam` is + * neither a directory nor a symbolic link to a directory. + * Steam is unlikely to work in this situation. + * See srt_system_info_dup_steam_data_path(). + * @SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK: `~/.steam/root` is not + * a symbolic link to the Steam installation. + * See srt_system_info_dup_steam_installation_path(). + * @SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY: `~/.steam/root` is + * neither a directory nor a symbolic link to a directory. + * Steam is unlikely to work in this situation. + * See srt_system_info_dup_steam_installation_path(). * * A bitfield with flags representing problems with the Steam * installation, or %SRT_STEAM_ISSUES_NONE (which is numerically zero) @@ -50,5 +68,9 @@ typedef enum SRT_STEAM_ISSUES_INTERNAL_ERROR = (1 << 0), SRT_STEAM_ISSUES_CANNOT_FIND = (1 << 1), SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK = (1 << 2), + SRT_STEAM_ISSUES_CANNOT_FIND_DATA = (1 << 3), + SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY = (1 << 4), + SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK = (1 << 5), + SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY = (1 << 6), SRT_STEAM_ISSUES_NONE = 0 } SrtSteamIssues; diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c index 930b3b167..988a28bf9 100644 --- a/steam-runtime-tools/system-info.c +++ b/steam-runtime-tools/system-info.c @@ -100,9 +100,10 @@ struct _SrtSystemInfo } locales; struct { - /* path != NULL or issues != NONE indicates we have already checked - * the Steam installation */ - gchar *path; + /* install_path != NULL or issues != NONE indicates we have already + * checked the Steam installation */ + gchar *install_path; + gchar *data_path; gchar *bin32; SrtSteamIssues issues; } steam; @@ -313,7 +314,8 @@ forget_steam (SrtSystemInfo *self) { forget_runtime (self); self->steam.issues = SRT_STEAM_ISSUES_NONE; - g_clear_pointer (&self->steam.path, g_free); + g_clear_pointer (&self->steam.install_path, g_free); + g_clear_pointer (&self->steam.data_path, g_free); g_clear_pointer (&self->steam.bin32, g_free); } @@ -1015,9 +1017,11 @@ static void ensure_steam_cached (SrtSystemInfo *self) { if (self->steam.issues == SRT_STEAM_ISSUES_NONE && - self->steam.path == NULL) + self->steam.install_path == NULL && + self->steam.data_path == NULL) self->steam.issues = _srt_steam_check (self->env, - &self->steam.path, + &self->steam.install_path, + &self->steam.data_path, &self->steam.bin32); } @@ -1046,13 +1050,28 @@ srt_system_info_get_steam_issues (SrtSystemInfo *self) * * Return the absolute path to the Steam installation in use (the * directory containing `steam.sh` and `ubuntu12_32/` among other - * files and directories, analogous to `C:\Program Files\Steam` in a - * typical Windows installation of Steam). This is typically of the form - * `/home/me/.local/share/Steam`. + * files and directories). + * + * This directory is analogous to `C:\Program Files\Steam` in a + * typical Windows installation of Steam, and is typically of the form + * `/home/me/.local/share/Steam`. It is also known as the "Steam root", + * and is canonically accessed via the symbolic link `~/.steam/root` + * (known as the "Steam root link"). * - * If the Steam installation could not be found, at least one flag will + * Under normal circumstances, this is the same directory as + * srt_system_info_dup_steam_data_path(). However, it is possible to + * construct situations where they are different, for example when a + * Steam developer tests a new client build in its own installation + * directory in conjunction with an existing data directory from the + * production client, or when Steam was first installed using a Debian + * package that suffered from + * [#916303](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916303) + * (which resulted in `~/.steam/steam` being a plain directory, not a + * symbolic link). + * + * If the Steam installation could not be found, flags will * be set in the result of srt_system_info_get_steam_issues() to indicate - * why. + * why: at least %SRT_STEAM_ISSUES_CANNOT_FIND, and possibly others. * * Returns: (transfer full) (type filename) (nullable): The absolute path * to the Steam installation, or %NULL if it could not be determined. @@ -1064,7 +1083,49 @@ srt_system_info_dup_steam_installation_path (SrtSystemInfo *self) g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL); ensure_steam_cached (self); - return g_strdup (self->steam.path); + return g_strdup (self->steam.install_path); +} + +/** + * srt_system_info_dup_steam_data_path: + * @self: The #SrtSystemInfo object + * + * Return the absolute path to the Steam data directory in use (the + * directory containing `appcache/`, `userdata/` and the default + * `steamapps/` or `SteamApps/` installation path for games, among other + * files and directories). + * + * This directory is analogous to `C:\Program Files\Steam` in a + * typical Windows installation of Steam, and is typically of the form + * `/home/me/.local/share/Steam`. It is canonically accessed via the + * symbolic link `~/.steam/steam` (known as the "Steam data link"). + * + * Under normal circumstances, this is the same directory as + * srt_system_info_dup_steam_installation_path(). However, it is possible + * to construct situations where they are different, for example when a + * Steam developer tests a new client build in its own installation + * directory in conjunction with an existing data directory from the + * production client, or when Steam was first installed using a Debian + * package that suffered from + * [#916303](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916303) + * (which resulted in `~/.steam/steam` being a plain directory, not a + * symbolic link). + * + * If the Steam data could not be found, flags will + * be set in the result of srt_system_info_get_steam_issues() to indicate + * why: at least %SRT_STEAM_ISSUES_CANNOT_FIND_DATA, and possibly others. + * + * Returns: (transfer full) (type filename) (nullable): The absolute path + * to the Steam installation, or %NULL if it could not be determined. + * Free with g_free(). + */ +gchar * +srt_system_info_dup_steam_data_path (SrtSystemInfo *self) +{ + g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL); + + ensure_steam_cached (self); + return g_strdup (self->steam.data_path); } /** @@ -1149,6 +1210,9 @@ srt_system_info_get_runtime_issues (SrtSystemInfo *self) * in use (the directory containing `run.sh`, `version.txt` and * similar files). * + * This will typically be below + * srt_system_info_dup_steam_installation_path(), unless overridden. + * * If the Steam Runtime has been disabled or could not be found, at * least one flag will be set in the result of * srt_system_info_get_runtime_issues() to indicate why. diff --git a/steam-runtime-tools/system-info.h b/steam-runtime-tools/system-info.h index 7caf98f9f..3de4da0f8 100644 --- a/steam-runtime-tools/system-info.h +++ b/steam-runtime-tools/system-info.h @@ -106,6 +106,7 @@ gchar *srt_system_info_dup_runtime_version (SrtSystemInfo *self); SrtSteamIssues srt_system_info_get_steam_issues (SrtSystemInfo *self); gchar *srt_system_info_dup_steam_installation_path (SrtSystemInfo *self); +gchar *srt_system_info_dup_steam_data_path (SrtSystemInfo *self); SrtLocaleIssues srt_system_info_get_locale_issues (SrtSystemInfo *self); SrtLocale *srt_system_info_check_locale (SrtSystemInfo *self, diff --git a/tests/fake-home.c b/tests/fake-home.c index c67da2f38..80ef0811b 100644 --- a/tests/fake-home.c +++ b/tests/fake-home.c @@ -52,10 +52,12 @@ fake_home_new (void) fake_home->create_pinning_libs = TRUE; fake_home->create_i386_folders = TRUE; fake_home->create_amd64_folders = TRUE; + fake_home->create_root_symlink = TRUE; fake_home->create_steam_symlink = TRUE; fake_home->create_steamrt_files = TRUE; fake_home->add_environments = TRUE; fake_home->has_debian_bug_916303 = FALSE; + fake_home->testing_beta_client = FALSE; return fake_home; } @@ -81,6 +83,7 @@ fake_home_create_structure (FakeHome *f) gchar *setup = NULL; gchar *version = NULL; gchar *dot_steam_bin32 = NULL; + gchar *dot_steam_root = NULL; gchar *dot_steam_steam = NULL; gchar *local_share = NULL; gchar *ld_path = NULL; @@ -94,19 +97,33 @@ fake_home_create_structure (FakeHome *f) dot_steam = g_build_filename (f->home, ".steam", NULL); if (f->has_debian_bug_916303) - f->steam_base_folder = g_strdup (dot_steam); + { + f->steam_install = g_strdup (dot_steam); + f->steam_data = g_build_filename (dot_steam, "steam", NULL); + } + else if (f->testing_beta_client) + { + f->steam_install = g_build_filename (f->home, "beta-client", NULL); + f->steam_data = g_build_filename (f->home, ".local", "share", + "Steam", NULL); + } else - f->steam_base_folder = g_build_filename (f->home, ".local", "share", - "Steam", NULL); + { + f->steam_install = g_build_filename (f->home, ".local", "share", + "Steam", NULL); + f->steam_data = g_strdup (f->steam_install); + } - f->runtime = g_build_filename (f->steam_base_folder, "ubuntu12_32", + f->runtime = g_build_filename (f->steam_install, "ubuntu12_32", "steam-runtime", NULL); scripts = g_build_filename (f->runtime, "scripts", NULL); if (g_mkdir_with_parents (dot_steam, 0755) != 0) goto out; - if (g_mkdir_with_parents (f->steam_base_folder, 0755) != 0) + if (g_mkdir_with_parents (f->steam_data, 0755) != 0) + goto out; + if (g_mkdir_with_parents (f->steam_install, 0755) != 0) goto out; if (g_mkdir_with_parents (scripts, 0755) != 0) goto out; @@ -177,13 +194,32 @@ fake_home_create_structure (FakeHome *f) goto out; } + if (f->create_root_symlink) + { + if (dot_steam_root == NULL) + dot_steam_root = g_build_filename (dot_steam, "root", NULL); + symlink = g_file_new_for_path (dot_steam_root); + + g_file_make_symbolic_link (symlink, f->steam_install, NULL, &error); + g_object_unref (symlink); + g_assert_no_error (error); + + dot_steam_bin32 = g_build_filename (dot_steam, "bin32", NULL); + symlink = g_file_new_for_path (dot_steam_bin32); + + ubuntu12_32 = g_build_filename (f->steam_install, "ubuntu12_32", NULL); + g_file_make_symbolic_link (symlink, ubuntu12_32, NULL, &error); + g_object_unref (symlink); + g_assert_no_error (error); + } + if (f->create_steam_symlink) { if (dot_steam_steam == NULL) dot_steam_steam = g_build_filename (dot_steam, "steam", NULL); symlink = g_file_new_for_path (dot_steam_steam); - g_file_make_symbolic_link (symlink, f->steam_base_folder, NULL, &error); + g_file_make_symbolic_link (symlink, f->steam_data, NULL, &error); g_object_unref (symlink); if (f->has_debian_bug_916303) { @@ -194,14 +230,6 @@ fake_home_create_structure (FakeHome *f) { g_assert_no_error (error); } - - dot_steam_bin32 = g_build_filename (dot_steam, "bin32", NULL); - symlink = g_file_new_for_path (dot_steam_bin32); - - ubuntu12_32 = g_build_filename (f->steam_base_folder, "ubuntu12_32", NULL); - g_file_make_symbolic_link (symlink, ubuntu12_32, NULL, &error); - g_object_unref (symlink); - g_assert_no_error (error); } local_share = g_build_filename (f->home, ".local", "share", NULL); @@ -250,6 +278,7 @@ fake_home_create_structure (FakeHome *f) g_free (setup); g_free (version); g_free (dot_steam_bin32); + g_free (dot_steam_root); g_free (dot_steam_steam); g_free (local_share); g_free (ld_path); @@ -277,7 +306,8 @@ fake_home_clean_up (FakeHome *f) g_debug ("Unable to remove the fake home directory: %s", f->home); g_free (f->home); - g_free (f->steam_base_folder); + g_free (f->steam_data); + g_free (f->steam_install); g_free (f->runtime); g_free (f->pinned_32); g_free (f->pinned_64); diff --git a/tests/fake-home.h b/tests/fake-home.h index 60a9846c0..197580f7f 100644 --- a/tests/fake-home.h +++ b/tests/fake-home.h @@ -33,13 +33,16 @@ typedef struct gboolean create_pinning_libs; gboolean create_i386_folders; gboolean create_amd64_folders; + gboolean create_root_symlink; gboolean create_steam_symlink; gboolean create_steamrt_files; gboolean add_environments; gboolean has_debian_bug_916303; + gboolean testing_beta_client; gchar *home; - gchar *steam_base_folder; + gchar *steam_install; + gchar *steam_data; gchar *runtime; gchar *pinned_32; gchar *pinned_64; diff --git a/tests/system-info-cli.c b/tests/system-info-cli.c index 4dc74e6d2..bb6afe0b3 100644 --- a/tests/system-info-cli.c +++ b/tests/system-info-cli.c @@ -586,9 +586,11 @@ steam_issues (Fixture *f, g_assert_true (json_object_has_member (json_sub_object, "issues")); array = json_object_get_array_member (json_sub_object, "issues"); - g_assert_cmpint (json_array_get_length (array), ==, 1); + g_assert_cmpint (json_array_get_length (array), ==, 2); g_assert_cmpstr (json_array_get_string_element (array, 0), ==, "dot-steam-steam-not-symlink"); + g_assert_cmpstr (json_array_get_string_element (array, 1), ==, + "dot-steam-steam-not-directory"); g_assert_true (json_object_has_member (json, "runtime")); json_sub_object = json_object_get_object_member (json, "runtime"); diff --git a/tests/system-info.c b/tests/system-info.c index cd27ec555..34d842c91 100644 --- a/tests/system-info.c +++ b/tests/system-info.c @@ -714,7 +714,7 @@ steam_runtime (Fixture *f, runtime_path = srt_system_info_dup_runtime_path (info); g_assert_cmpstr (runtime_path, ==, fake_home->runtime); installation_path = srt_system_info_dup_steam_installation_path (info); - g_assert_cmpstr (installation_path, ==, fake_home->steam_base_folder); + g_assert_cmpstr (installation_path, ==, fake_home->steam_install); g_free (runtime_path); g_free (installation_path); @@ -724,7 +724,7 @@ steam_runtime (Fixture *f, runtime_path = srt_system_info_dup_runtime_path (info); g_assert_cmpstr (runtime_path, ==, fake_home->runtime); installation_path = srt_system_info_dup_steam_installation_path (info); - g_assert_cmpstr (installation_path, ==, fake_home->steam_base_folder); + g_assert_cmpstr (installation_path, ==, fake_home->steam_install); /* Check for Steam issues */ steam_issues = srt_system_info_get_steam_issues (info); @@ -1019,7 +1019,7 @@ runtime_unexpected_location (Fixture *f, { SrtSystemInfo *info; SrtRuntimeIssues issues; - gchar *dot_steam_steam = NULL; + gchar *dot_steam_root = NULL; gchar *my_runtime = NULL; gchar *ld_path = NULL; gchar *env_path = NULL; @@ -1029,19 +1029,19 @@ runtime_unexpected_location (Fixture *f, FakeHome *fake_home; fake_home = fake_home_new (); - fake_home->create_steam_symlink = FALSE; + fake_home->create_root_symlink = FALSE; fake_home_create_structure (fake_home); info = srt_system_info_new (NULL); - dot_steam_steam = g_build_filename (fake_home->home, ".steam", "steam", NULL); + dot_steam_root = g_build_filename (fake_home->home, ".steam", "root", NULL); - my_runtime = g_build_filename (fake_home->steam_base_folder, "ubuntu12_32", + my_runtime = g_build_filename (fake_home->steam_install, "ubuntu12_32", "my-runtime", NULL); /* Create a new homedir/.steam/steam symlink that doesn't point to * the expected steam runtime path. */ - symlink = g_file_new_for_path (dot_steam_steam); + symlink = g_file_new_for_path (dot_steam_root); g_file_make_symbolic_link (symlink, fake_home->pinned_64, NULL, &error); g_assert_no_error (error); srt_system_info_set_environ (info, fake_home->env); @@ -1063,8 +1063,8 @@ runtime_unexpected_location (Fixture *f, env_path = g_strjoinv ("my-runtime", parts); g_rename (fake_home->runtime, my_runtime); - g_remove (dot_steam_steam); - symlink = g_file_new_for_path (dot_steam_steam); + g_remove (dot_steam_root); + symlink = g_file_new_for_path (dot_steam_root); g_file_make_symbolic_link (symlink, my_runtime, NULL, &error); g_assert_no_error (error); fake_home->env = g_environ_setenv (fake_home->env, "LD_LIBRARY_PATH", ld_path, TRUE); @@ -1078,7 +1078,7 @@ runtime_unexpected_location (Fixture *f, fake_home_clean_up (fake_home); g_object_unref (symlink); g_object_unref (info); - g_free (dot_steam_steam); + g_free (dot_steam_root); g_free (my_runtime); g_free (ld_path); g_free (env_path); @@ -1109,30 +1109,26 @@ steam_symlink (Fixture *f, dot_steam_steam = g_build_filename (fake_home->home, ".steam", "steam", NULL); dot_steam_root = g_build_filename (fake_home->home, ".steam", "root", NULL); dot_steam_bin32 = g_build_filename (fake_home->home, ".steam", "bin32", NULL); - ubuntu12_32 = g_build_filename (fake_home->steam_base_folder, "ubuntu12_32", NULL); + ubuntu12_32 = g_build_filename (fake_home->steam_install, "ubuntu12_32", NULL); /* We don't have a homedir/.steam/steam symlink. */ srt_system_info_set_environ (info, fake_home->env); issues = srt_system_info_get_steam_issues (info); - g_assert_cmpint (SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK, ==, issues); - - /* Create the homedir/.steam/root symlink. */ - symlink = g_file_new_for_path (dot_steam_root); - g_file_make_symbolic_link (symlink, fake_home->steam_base_folder, NULL, &error); - g_assert_no_error (error); - srt_system_info_set_environ (info, fake_home->env); - issues = srt_system_info_get_steam_issues (info); - g_assert_cmpint (SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK, ==, issues); - g_object_unref (symlink); + g_assert_cmpint ((SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK + | SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY), ==, issues); /* Remove homedir/.steam/root symlink and create homedir/.steam/bin32 symlink. */ g_remove (dot_steam_root); + g_remove (dot_steam_bin32); symlink = g_file_new_for_path (dot_steam_bin32); g_file_make_symbolic_link (symlink, ubuntu12_32, NULL, &error); g_assert_no_error (error); srt_system_info_set_environ (info, fake_home->env); issues = srt_system_info_get_steam_issues (info); - g_assert_cmpint (SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK, ==, issues); + g_assert_cmpint ((SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK + | SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY + | SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK + | SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY), ==, issues); /* Remove the homedir/.steam/bin32 symlink and set XDG_DATA_HOME env to a * folder that is not the expected homedir/.local/share */ @@ -1141,8 +1137,12 @@ steam_symlink (Fixture *f, fake_home->env = g_environ_setenv (fake_home->env, "XDG_DATA_HOME", data_home, TRUE); srt_system_info_set_environ (info, fake_home->env); issues = srt_system_info_get_steam_issues (info); - g_assert_cmpint (SRT_STEAM_ISSUES_CANNOT_FIND | - SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK, ==, issues); + g_assert_cmpint ((SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK + | SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_DIRECTORY + | SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_SYMLINK + | SRT_STEAM_ISSUES_DOT_STEAM_ROOT_NOT_DIRECTORY + | SRT_STEAM_ISSUES_CANNOT_FIND + | SRT_STEAM_ISSUES_CANNOT_FIND_DATA), ==, issues); installation_path = srt_system_info_dup_steam_installation_path (info); g_assert_cmpstr (installation_path, ==, NULL); @@ -1167,6 +1167,8 @@ debian_bug_916303 (Fixture *f, SrtSystemInfo *info; SrtSteamIssues issues; FakeHome *fake_home; + gchar *installation_path; + gchar *data_path; fake_home = fake_home_new (); fake_home->has_debian_bug_916303 = TRUE; @@ -1177,9 +1179,50 @@ debian_bug_916303 (Fixture *f, issues = srt_system_info_get_steam_issues (info); g_assert_cmpint (issues, ==, SRT_STEAM_ISSUES_DOT_STEAM_STEAM_NOT_SYMLINK); + installation_path = srt_system_info_dup_steam_installation_path (info); + g_assert_cmpstr (installation_path, ==, fake_home->steam_install); + g_assert_true (g_str_has_suffix (installation_path, "/.steam")); + data_path = srt_system_info_dup_steam_data_path (info); + g_assert_cmpstr (data_path, ==, fake_home->steam_data); + g_assert_true (g_str_has_suffix (data_path, "/.steam/steam")); fake_home_clean_up (fake_home); g_object_unref (info); + g_free (installation_path); + g_free (data_path); +} + +/* Behave as though we're testing a beta client. */ +static void +testing_beta_client (Fixture *f, + gconstpointer context) +{ + SrtSystemInfo *info; + SrtSteamIssues issues; + FakeHome *fake_home; + gchar *installation_path; + gchar *data_path; + + fake_home = fake_home_new (); + fake_home->testing_beta_client = TRUE; + fake_home_create_structure (fake_home); + + info = srt_system_info_new (NULL); + srt_system_info_set_environ (info, fake_home->env); + + issues = srt_system_info_get_steam_issues (info); + g_assert_cmpint (issues, ==, 0); + installation_path = srt_system_info_dup_steam_installation_path (info); + g_assert_cmpstr (installation_path, ==, fake_home->steam_install); + g_assert_true (g_str_has_suffix (installation_path, "/beta-client")); + data_path = srt_system_info_dup_steam_data_path (info); + g_assert_cmpstr (data_path, ==, fake_home->steam_data); + g_assert_true (g_str_has_suffix (data_path, "/.local/share/Steam")); + + fake_home_clean_up (fake_home); + g_object_unref (info); + g_free (installation_path); + g_free (data_path); } int @@ -1220,6 +1263,8 @@ main (int argc, setup, steam_symlink, teardown); g_test_add ("/system-info/debian_bug_916303", Fixture, NULL, setup, debian_bug_916303, teardown); + g_test_add ("/system-info/testing_beta_client", Fixture, NULL, + setup, testing_beta_client, teardown); return g_test_run (); } -- GitLab