diff options
Diffstat (limited to '')
-rw-r--r-- | lib/gs-self-test.c | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c new file mode 100644 index 0000000..c38f452 --- /dev/null +++ b/lib/gs-self-test.c @@ -0,0 +1,786 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2013-2017 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2015-2018 Kalev Lember <klember@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include "gnome-software-private.h" + +#include "gs-debug.h" +#include "gs-test.h" + +static gboolean +gs_app_list_filter_cb (GsApp *app, gpointer user_data) +{ + if (g_strcmp0 (gs_app_get_id (app), "a") == 0) + return FALSE; + if (g_strcmp0 (gs_app_get_id (app), "c") == 0) + return FALSE; + return TRUE; +} + +static void +gs_utils_url_func (void) +{ + g_autofree gchar *path1 = NULL; + g_autofree gchar *path2 = NULL; + g_autofree gchar *path3 = NULL; + g_autofree gchar *scheme1 = NULL; + g_autofree gchar *scheme2 = NULL; + + scheme1 = gs_utils_get_url_scheme ("appstream://gimp.desktop"); + g_assert_cmpstr (scheme1, ==, "appstream"); + scheme2 = gs_utils_get_url_scheme ("appstream:gimp.desktop"); + g_assert_cmpstr (scheme2, ==, "appstream"); + + path1 = gs_utils_get_url_path ("appstream://gimp.desktop"); + g_assert_cmpstr (path1, ==, "gimp.desktop"); + path2 = gs_utils_get_url_path ("appstream:gimp.desktop"); + g_assert_cmpstr (path2, ==, "gimp.desktop"); + path3 = gs_utils_get_url_path ("apt:/gimp"); + g_assert_cmpstr (path3, ==, "gimp"); +} + +static void +gs_utils_wilson_func (void) +{ + g_assert_cmpint ((gint64) gs_utils_get_wilson_rating (0, 0, 0, 0, 0), ==, -1); + g_assert_cmpint ((gint64) gs_utils_get_wilson_rating (0, 0, 0, 0, 400), ==, 100); + g_assert_cmpint ((gint64) gs_utils_get_wilson_rating (10, 0, 0, 0, 400), ==, 98); + g_assert_cmpint ((gint64) gs_utils_get_wilson_rating (0, 0, 0, 0, 1), ==, 76); + g_assert_cmpint ((gint64) gs_utils_get_wilson_rating (5, 4, 20, 100, 400), ==, 93); +} + +static void +gs_os_release_func (void) +{ + g_autofree gchar *fn = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsOsRelease) os_release = NULL; + + fn = gs_test_get_filename (TESTDATADIR, "tests/os-release"); + g_assert (fn != NULL); + g_setenv ("GS_SELF_TEST_OS_RELEASE_FILENAME", fn, TRUE); + + os_release = gs_os_release_new (&error); + g_assert_no_error (error); + g_assert (os_release != NULL); + g_assert_cmpstr (gs_os_release_get_id (os_release), ==, "fedora"); + g_assert_cmpstr (gs_os_release_get_name (os_release), ==, "Fedora"); + g_assert_cmpstr (gs_os_release_get_version (os_release), ==, "25 (Workstation Edition)"); + g_assert_cmpstr (gs_os_release_get_version_id (os_release), ==, "25"); + g_assert_cmpstr (gs_os_release_get_pretty_name (os_release), ==, "Fedora 25 (Workstation Edition)"); +} + +static void +gs_utils_append_kv_func (void) +{ + g_autoptr(GString) str = g_string_new (NULL); + + /* normal */ + gs_utils_append_key_value (str, 5, "key", "val"); + g_assert_cmpstr (str->str, ==, "key: val\n"); + + /* oversize */ + g_string_truncate (str, 0); + gs_utils_append_key_value (str, 5, "longkey", "val"); + g_assert_cmpstr (str->str, ==, "longkey: val\n"); + + /* null key */ + g_string_truncate (str, 0); + gs_utils_append_key_value (str, 5, NULL, "val"); + g_assert_cmpstr (str->str, ==, " val\n"); + + /* zero align key */ + g_string_truncate (str, 0); + gs_utils_append_key_value (str, 0, "key", "val"); + g_assert_cmpstr (str->str, ==, "key: val\n"); +} + +static void +gs_utils_cache_func (void) +{ + g_autofree gchar *fn1 = NULL; + g_autofree gchar *fn2 = NULL; + g_autoptr(GError) error = NULL; + + fn1 = gs_utils_get_cache_filename ("test", + "http://www.foo.bar/baz", + GS_UTILS_CACHE_FLAG_WRITEABLE | + GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, + &error); + g_assert_no_error (error); + g_assert_cmpstr (fn1, !=, NULL); + g_assert (g_str_has_prefix (fn1, g_get_user_cache_dir ())); + g_assert (g_str_has_suffix (fn1, "test/baz")); + + fn2 = gs_utils_get_cache_filename ("test", + "http://www.foo.bar/baz", + GS_UTILS_CACHE_FLAG_WRITEABLE | + GS_UTILS_CACHE_FLAG_USE_HASH | + GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, + &error); + g_assert_no_error (error); + g_assert_cmpstr (fn2, !=, NULL); + g_assert (g_str_has_prefix (fn2, g_get_user_cache_dir ())); + g_assert (g_str_has_suffix (fn2, "test/295099f59d12b3eb0b955325fcb699cd23792a89-baz")); +} + +static void +gs_utils_error_func (void) +{ + g_autofree gchar *app_id = NULL; + g_autofree gchar *origin_id = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsApp) app = gs_app_new ("gimp.desktop"); + g_autoptr(GsApp) origin = gs_app_new ("gimp-repo"); + + for (guint i = 0; i < GS_PLUGIN_ERROR_LAST; i++) + g_assert (gs_plugin_error_to_string (i) != NULL); + + /* noop */ + gs_utils_error_add_app_id (&error, app); + gs_utils_error_add_origin_id (&error, origin); + + g_set_error (&error, + GS_PLUGIN_ERROR, + GS_PLUGIN_ERROR_DOWNLOAD_FAILED, + "failed"); + g_assert_cmpstr (error->message, ==, "failed"); + gs_utils_error_add_app_id (&error, app); + gs_utils_error_add_origin_id (&error, origin); + g_assert_cmpstr (error->message, ==, "[*/*/*/gimp-repo/*] {*/*/*/gimp.desktop/*} failed"); + + /* find and strip any unique IDs from the error message */ + for (guint i = 0; i < 2; i++) { + if (app_id == NULL) + app_id = gs_utils_error_strip_app_id (error); + if (origin_id == NULL) + origin_id = gs_utils_error_strip_origin_id (error); + } + + g_assert_cmpstr (app_id, ==, "*/*/*/gimp.desktop/*"); + g_assert_cmpstr (origin_id, ==, "*/*/*/gimp-repo/*"); + g_assert_cmpstr (error->message, ==, "failed"); +} + +static void +gs_plugin_download_rewrite_func (void) +{ + g_autofree gchar *css = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GDBusConnection) bus_connection = NULL; + g_autoptr(GsPlugin) plugin = NULL; + const gchar *resource = "background:\n" + " url('file://" DATADIR "/gnome-software/featured-maps.png')\n" + " url('file://" DATADIR "/gnome-software/featured-maps-bg.png')\n" + " bottom center / contain no-repeat;\n"; + + /* only when installed */ + if (!g_file_test (DATADIR "/gnome-software/featured-maps.png", G_FILE_TEST_EXISTS)) { + g_test_skip ("not installed"); + return; + } + + /* test rewrite */ + bus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + plugin = gs_plugin_new (bus_connection, bus_connection); + gs_plugin_set_name (plugin, "self-test"); + css = gs_plugin_download_rewrite_resource (plugin, + NULL, /* app */ + resource, + NULL, + &error); + g_assert_no_error (error); + g_assert (css != NULL); +} + +static void +gs_plugin_func (void) +{ + GsAppList *list; + GsAppList *list_dup; + GsAppList *list_remove; + GsApp *app; + + /* check enums converted */ + for (guint i = 0; i < GS_PLUGIN_ACTION_LAST; i++) { + const gchar *tmp = gs_plugin_action_to_string (i); + if (tmp == NULL) + g_critical ("failed to convert %u", i); + g_assert_cmpint (gs_plugin_action_from_string (tmp), ==, i); + } + for (guint i = 1; i < GS_PLUGIN_ACTION_LAST; i++) { + const gchar *tmp = gs_plugin_action_to_function_name (i); + if (tmp == NULL) { + /* These do not have function, they exist only for better error messages. */ + if (i == GS_PLUGIN_ACTION_INSTALL_REPO || + i == GS_PLUGIN_ACTION_REMOVE_REPO || + i == GS_PLUGIN_ACTION_ENABLE_REPO || + i == GS_PLUGIN_ACTION_DISABLE_REPO) + continue; + g_critical ("failed to convert %u", i); + } + } + + /* add a couple of duplicate IDs */ + app = gs_app_new ("a"); + list = gs_app_list_new (); + gs_app_list_add (list, app); + g_object_unref (app); + + /* test refcounting */ + g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list, 0)), ==, "a"); + list_dup = gs_app_list_copy (list); + g_object_unref (list); + g_assert_cmpint (gs_app_list_length (list_dup), ==, 1); + g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list_dup, 0)), ==, "a"); + g_object_unref (list_dup); + + /* test removing objects */ + app = gs_app_new ("a"); + list_remove = gs_app_list_new (); + gs_app_list_add (list_remove, app); + g_object_unref (app); + app = gs_app_new ("b"); + gs_app_list_add (list_remove, app); + g_object_unref (app); + app = gs_app_new ("c"); + gs_app_list_add (list_remove, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 3); + gs_app_list_filter (list_remove, gs_app_list_filter_cb, NULL); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 1); + g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list_remove, 0)), ==, "b"); + + /* test removing duplicates at runtime */ + app = gs_app_new ("b"); + gs_app_list_add (list_remove, app); + g_object_unref (app); + app = gs_app_new ("b"); + gs_app_list_add (list_remove, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 1); + g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list_remove, 0)), ==, "b"); + g_object_unref (list_remove); + + /* test removing duplicates when lazy-loading */ + list_remove = gs_app_list_new (); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + gs_app_set_id (app, "e"); + g_object_unref (app); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + gs_app_set_id (app, "e"); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 2); + gs_app_list_filter_duplicates (list_remove, GS_APP_LIST_FILTER_FLAG_NONE); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 1); + g_object_unref (list_remove); + + /* test removing duplicates when some apps have no app ID */ + list_remove = gs_app_list_new (); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + g_object_unref (app); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + g_object_unref (app); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + gs_app_set_id (app, "e"); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 3); + gs_app_list_filter_duplicates (list_remove, GS_APP_LIST_FILTER_FLAG_NONE); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 3); + g_object_unref (list_remove); + + /* remove lazy-loaded app */ + list_remove = gs_app_list_new (); + app = gs_app_new (NULL); + gs_app_list_add (list_remove, app); + gs_app_list_remove (list_remove, app); + g_assert_cmpint (gs_app_list_length (list_remove), ==, 0); + g_object_unref (app); + g_object_unref (list_remove); + + /* respect priority when deduplicating */ + list = gs_app_list_new (); + app = gs_app_new ("e"); + gs_app_set_unique_id (app, "user/foo/*/e/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 0); + g_object_unref (app); + app = gs_app_new ("e"); + gs_app_set_unique_id (app, "user/bar/*/e/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 99); + g_object_unref (app); + app = gs_app_new ("e"); + gs_app_set_unique_id (app, "user/baz/*/e/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 50); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 3); + gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_KEY_ID); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, "user/bar/*/e/*"); + g_object_unref (list); + + /* respect priority (using name and version) when deduplicating */ + list = gs_app_list_new (); + app = gs_app_new ("e"); + gs_app_add_source (app, "foo"); + gs_app_set_version (app, "1.2.3"); + gs_app_set_unique_id (app, "user/foo/repo/*/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 0); + g_object_unref (app); + app = gs_app_new ("e"); + gs_app_add_source (app, "foo"); + gs_app_set_version (app, "1.2.3"); + gs_app_set_unique_id (app, "user/foo/repo-security/*/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 99); + g_object_unref (app); + app = gs_app_new ("e"); + gs_app_add_source (app, "foo"); + gs_app_set_version (app, "1.2.3"); + gs_app_set_unique_id (app, "user/foo/repo-universe/*/*"); + gs_app_list_add (list, app); + gs_app_set_priority (app, 50); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 3); + gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_KEY_ID | + GS_APP_LIST_FILTER_FLAG_KEY_SOURCE | + GS_APP_LIST_FILTER_FLAG_KEY_VERSION); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, "user/foo/repo-security/*/*"); + g_object_unref (list); + + /* prefer installed applications */ + list = gs_app_list_new (); + app = gs_app_new ("e"); + gs_app_set_state (app, GS_APP_STATE_INSTALLED); + gs_app_set_unique_id (app, "user/foo/*/e/*"); + gs_app_set_priority (app, 0); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("e"); + gs_app_set_state (app, GS_APP_STATE_AVAILABLE); + gs_app_set_unique_id (app, "user/bar/*/e/*"); + gs_app_set_priority (app, 100); + gs_app_list_add (list, app); + g_object_unref (app); + gs_app_list_filter_duplicates (list, + GS_APP_LIST_FILTER_FLAG_KEY_ID | + GS_APP_LIST_FILTER_FLAG_PREFER_INSTALLED); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, "user/foo/*/e/*"); + g_object_unref (list); + + /* use the provides ID to dedupe */ + list = gs_app_list_new (); + app = gs_app_new ("gimp.desktop"); + gs_app_set_unique_id (app, "user/fedora/*/gimp.desktop/*"); + gs_app_set_priority (app, 0); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("org.gimp.GIMP"); + gs_app_add_provided_item (app, + AS_PROVIDED_KIND_ID, + "gimp.desktop"); + gs_app_set_unique_id (app, "user/flathub/*/org.gimp.GIMP/*"); + gs_app_set_priority (app, 100); + gs_app_list_add (list, app); + g_object_unref (app); + gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, + "user/flathub/*/org.gimp.GIMP/*"); + g_object_unref (list); + + /* use globs when adding */ + list = gs_app_list_new (); + app = gs_app_new ("b"); + gs_app_set_unique_id (app, "a/b/c/d/e"); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("b"); + gs_app_set_unique_id (app, "a/b/c/*/e"); + gs_app_list_add (list, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list, 0)), ==, "b"); + g_object_unref (list); + + /* lookup with a wildcard */ + list = gs_app_list_new (); + app = gs_app_new ("b"); + gs_app_set_unique_id (app, "a/b/c/d/e"); + gs_app_list_add (list, app); + g_object_unref (app); + g_assert (gs_app_list_lookup (list, "a/b/c/d/e") != NULL); + g_assert (gs_app_list_lookup (list, "a/b/c/d/*") != NULL); + g_assert (gs_app_list_lookup (list, "*/b/c/d/e") != NULL); + g_assert (gs_app_list_lookup (list, "x/x/x/x/x") == NULL); + g_object_unref (list); + + /* allow duplicating a wildcard */ + list = gs_app_list_new (); + app = gs_app_new ("gimp.desktop"); + gs_app_add_quirk (app, GS_APP_QUIRK_IS_WILDCARD); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("gimp.desktop"); + gs_app_set_unique_id (app, "system/flatpak/*/gimp.desktop/stable"); + gs_app_list_add (list, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 2); + g_object_unref (list); + + /* allow duplicating a wildcard */ + list = gs_app_list_new (); + app = gs_app_new ("gimp.desktop"); + gs_app_add_quirk (app, GS_APP_QUIRK_IS_WILDCARD); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("gimp.desktop"); + gs_app_add_quirk (app, GS_APP_QUIRK_IS_WILDCARD); + gs_app_list_add (list, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + g_object_unref (list); + + /* add a list to a list */ + list = gs_app_list_new (); + list_dup = gs_app_list_new (); + app = gs_app_new ("a"); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("b"); + gs_app_list_add (list_dup, app); + g_object_unref (app); + gs_app_list_add_list (list, list_dup); + g_assert_cmpint (gs_app_list_length (list), ==, 2); + g_assert_cmpint (gs_app_list_length (list_dup), ==, 1); + g_object_unref (list); + g_object_unref (list_dup); + + /* remove apps from the list */ + list = gs_app_list_new (); + app = gs_app_new ("a"); + gs_app_list_add (list, app); + gs_app_list_remove (list, app); + g_object_unref (app); + g_assert_cmpint (gs_app_list_length (list), ==, 0); + g_object_unref (list); + + /* truncate list */ + list = gs_app_list_new (); + app = gs_app_new ("a"); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("b"); + gs_app_list_add (list, app); + g_object_unref (app); + app = gs_app_new ("c"); + gs_app_list_add (list, app); + g_object_unref (app); + g_assert (!gs_app_list_has_flag (list, GS_APP_LIST_FLAG_IS_TRUNCATED)); + g_assert_cmpint (gs_app_list_get_size_peak (list), ==, 3); + gs_app_list_truncate (list, 3); + g_assert_cmpint (gs_app_list_length (list), ==, 3); + g_assert (gs_app_list_has_flag (list, GS_APP_LIST_FLAG_IS_TRUNCATED)); + g_assert_cmpint (gs_app_list_get_size_peak (list), ==, 3); + gs_app_list_truncate (list, 2); + g_assert_cmpint (gs_app_list_length (list), ==, 2); + gs_app_list_truncate (list, 1); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + gs_app_list_truncate (list, 0); + g_assert_cmpint (gs_app_list_length (list), ==, 0); + g_assert_cmpint (gs_app_list_get_size_peak (list), ==, 3); + g_object_unref (list); +} + +static gpointer +gs_app_thread_cb (gpointer data) +{ + GsApp *app = GS_APP (data); + for (guint i = 0; i < 10000; i++) { + g_assert_cmpstr (gs_app_get_unique_id (app), !=, NULL); + gs_app_set_branch (app, "master"); + g_assert_cmpstr (gs_app_get_unique_id (app), !=, NULL); + gs_app_set_branch (app, "stable"); + } + return NULL; +} + +static void +gs_app_thread_func (gconstpointer user_data) +{ + GsDebug *debug = GS_DEBUG ((void *)user_data); + GThread *thread1; + GThread *thread2; + g_autoptr(GsApp) app = gs_app_new ("gimp.desktop"); + + /* try really hard to cause a threading problem */ + gs_debug_set_verbose (debug, FALSE); + thread1 = g_thread_new ("thread1", gs_app_thread_cb, app); + thread2 = g_thread_new ("thread2", gs_app_thread_cb, app); + g_thread_join (thread1); /* consumes the reference */ + g_thread_join (thread2); + gs_debug_set_verbose (debug, TRUE); +} + +static void +gs_app_unique_id_func (void) +{ + g_autoptr(GsApp) app = gs_app_new (NULL); + g_autofree gchar *data_id = NULL; + const gchar *unique_id; + + unique_id = "system/flatpak/gnome/org.gnome.Software/master"; + gs_app_set_from_unique_id (app, unique_id, AS_COMPONENT_KIND_DESKTOP_APP); + g_assert (GS_IS_APP (app)); + g_assert_cmpint (gs_app_get_scope (app), ==, AS_COMPONENT_SCOPE_SYSTEM); + g_assert_cmpint (gs_app_get_bundle_kind (app), ==, AS_BUNDLE_KIND_FLATPAK); + g_assert_cmpstr (gs_app_get_origin (app), ==, "gnome"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP); + g_assert_cmpstr (gs_app_get_id (app), ==, "org.gnome.Software"); + g_assert_cmpstr (gs_app_get_branch (app), ==, "master"); + + /* test conversions from 6-part IDs */ + data_id = gs_utils_unique_id_compat_convert (unique_id); + g_assert_cmpstr (data_id, ==, unique_id); + g_clear_pointer (&data_id, g_free); + + data_id = gs_utils_unique_id_compat_convert ("not a unique ID"); + g_assert_null (data_id); + + data_id = gs_utils_unique_id_compat_convert ("system/flatpak/gnome/desktop-app/org.gnome.Software/master"); + g_assert_cmpstr (data_id, ==, unique_id); + g_clear_pointer (&data_id, g_free); +} + +static void +gs_app_addons_func (void) +{ + g_autoptr(GsApp) app = gs_app_new ("test.desktop"); + g_autoptr(GsApp) addon = NULL; + g_autoptr(GsAppList) addons_list = NULL; + + /* create, add then drop ref, so @app has the only refcount of addon */ + addon = gs_app_new ("test.desktop"); + addons_list = gs_app_list_new (); + gs_app_list_add (addons_list, addon); + + gs_app_add_addons (app, addons_list); + + gs_app_remove_addon (app, addon); +} + +static void +gs_app_func (void) +{ + g_autoptr(GsApp) app = NULL; + + app = gs_app_new ("gnome-software.desktop"); + g_assert (GS_IS_APP (app)); + g_assert_cmpstr (gs_app_get_id (app), ==, "gnome-software.desktop"); + + /* check we clean up the version, but not at the expense of having + * the same string as the update version */ + gs_app_set_version (app, "2.8.6-3.fc20"); + gs_app_set_update_version (app, "2.8.6-4.fc20"); + g_assert_cmpstr (gs_app_get_version (app), ==, "2.8.6-3.fc20"); + g_assert_cmpstr (gs_app_get_update_version (app), ==, "2.8.6-4.fc20"); + g_assert_cmpstr (gs_app_get_version_ui (app), ==, "2.8.6-3"); + g_assert_cmpstr (gs_app_get_update_version_ui (app), ==, "2.8.6-4"); + + /* check the quality stuff works */ + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "dave"); + g_assert_cmpstr (gs_app_get_name (app), ==, "dave"); + gs_app_set_name (app, GS_APP_QUALITY_LOWEST, "brian"); + g_assert_cmpstr (gs_app_get_name (app), ==, "dave"); + gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, "hugh"); + g_assert_cmpstr (gs_app_get_name (app), ==, "hugh"); + + /* check non-transient state saving */ + gs_app_set_state (app, GS_APP_STATE_INSTALLED); + g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED); + gs_app_set_state (app, GS_APP_STATE_REMOVING); + g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_REMOVING); + gs_app_set_state_recover (app); // simulate an error + g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED); + + /* try again */ + gs_app_set_state (app, GS_APP_STATE_REMOVING); + g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_REMOVING); + gs_app_set_state_recover (app); // simulate an error + g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED); + + /* correctly parse URL */ + gs_app_set_origin_hostname (app, "https://mirrors.fedoraproject.org/metalink"); + g_assert_cmpstr (gs_app_get_origin_hostname (app), ==, "fedoraproject.org"); + gs_app_set_origin_hostname (app, "file:///home/hughsie"); + g_assert_cmpstr (gs_app_get_origin_hostname (app), ==, "localhost"); + + /* check setting the progress */ + gs_app_set_progress (app, 42); + g_assert_cmpuint (gs_app_get_progress (app), ==, 42); + gs_app_set_progress (app, 0); + g_assert_cmpuint (gs_app_get_progress (app), ==, 0); + gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); + g_assert_cmpuint (gs_app_get_progress (app), ==, GS_APP_PROGRESS_UNKNOWN); + g_assert_false ((gint) 0 <= (gint) GS_APP_PROGRESS_UNKNOWN && GS_APP_PROGRESS_UNKNOWN <= 100); + + /* check pending action */ + g_assert_cmpuint (gs_app_get_pending_action (app), ==, GS_PLUGIN_ACTION_UNKNOWN); + gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE); + gs_app_set_pending_action (app, GS_PLUGIN_ACTION_UPDATE); + g_assert_cmpuint (gs_app_get_pending_action (app), ==, GS_PLUGIN_ACTION_UPDATE); + gs_app_set_state (app, GS_APP_STATE_INSTALLING); + g_assert_cmpuint (gs_app_get_pending_action (app), ==, GS_PLUGIN_ACTION_UNKNOWN); + gs_app_set_state_recover (app); +} + +static void +gs_app_progress_clamping_func (void) +{ + g_autoptr(GsApp) app = NULL; + + if (g_test_subprocess ()) { + app = gs_app_new ("gnome-software.desktop"); + gs_app_set_progress (app, 142); + g_assert_cmpuint (gs_app_get_progress (app), ==, 100); + } else { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*cannot set 142% for *, setting instead: 100%*"); + } +} + +static void +gs_app_list_wildcard_dedupe_func (void) +{ + g_autoptr(GsAppList) list = gs_app_list_new (); + g_autoptr(GsApp) app1 = gs_app_new ("app"); + g_autoptr(GsApp) app2 = gs_app_new ("app"); + + gs_app_add_quirk (app1, GS_APP_QUIRK_IS_WILDCARD); + gs_app_list_add (list, app1); + gs_app_add_quirk (app2, GS_APP_QUIRK_IS_WILDCARD); + gs_app_list_add (list, app2); + g_assert_cmpint (gs_app_list_length (list), ==, 1); +} + +static void +gs_app_list_func (void) +{ + g_autoptr(GsAppList) list = gs_app_list_new (); + g_autoptr(GsApp) app1 = gs_app_new ("app1"); + g_autoptr(GsApp) app2 = gs_app_new ("app2"); + + /* turn on */ + gs_app_list_add_flag (list, GS_APP_LIST_FLAG_WATCH_APPS); + + g_assert_cmpint (gs_app_list_get_progress (list), ==, 0); + g_assert_cmpint (gs_app_list_get_state (list), ==, GS_APP_STATE_UNKNOWN); + gs_app_list_add (list, app1); + gs_app_set_progress (app1, 75); + gs_app_set_state (app1, GS_APP_STATE_AVAILABLE); + gs_app_set_state (app1, GS_APP_STATE_INSTALLING); + gs_test_flush_main_context (); + g_assert_cmpint (gs_app_list_get_progress (list), ==, 75); + g_assert_cmpint (gs_app_list_get_state (list), ==, GS_APP_STATE_INSTALLING); + + gs_app_list_add (list, app2); + gs_app_set_progress (app2, 25); + gs_test_flush_main_context (); + g_assert_cmpint (gs_app_list_get_progress (list), ==, 50); + g_assert_cmpint (gs_app_list_get_state (list), ==, GS_APP_STATE_INSTALLING); + + gs_app_list_remove (list, app1); + g_assert_cmpint (gs_app_list_get_progress (list), ==, 25); + g_assert_cmpint (gs_app_list_get_state (list), ==, GS_APP_STATE_UNKNOWN); +} + +static void +gs_app_list_performance_func (void) +{ + g_autoptr(GPtrArray) apps = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + g_autoptr(GsAppList) list = gs_app_list_new (); + g_autoptr(GTimer) timer = NULL; + + /* create a few apps */ + for (guint i = 0; i < 500; i++) { + g_autofree gchar *id = g_strdup_printf ("%03u.desktop", i); + g_ptr_array_add (apps, gs_app_new (id)); + } + + /* add them to the list */ + timer = g_timer_new (); + for (guint i = 0; i < apps->len; i++) { + GsApp *app = g_ptr_array_index (apps, i); + gs_app_list_add (list, app); + } + g_print ("%.2fms ", g_timer_elapsed (timer, NULL) * 1000); +} + +static void +gs_app_list_related_func (void) +{ + g_autoptr(GsAppList) list = gs_app_list_new (); + g_autoptr(GsApp) app = gs_app_new ("app"); + g_autoptr(GsApp) related = gs_app_new ("related"); + + /* turn on */ + gs_app_list_add_flag (list, + GS_APP_LIST_FLAG_WATCH_APPS | + GS_APP_LIST_FLAG_WATCH_APPS_RELATED); + gs_app_add_related (app, related); + gs_app_list_add (list, app); + + gs_app_set_progress (app, 75); + gs_app_set_progress (related, 25); + gs_test_flush_main_context (); + g_assert_cmpint (gs_app_list_get_progress (list), ==, 50); +} + +int +main (int argc, char **argv) +{ + g_autoptr(GsDebug) debug = gs_debug_new (NULL, TRUE, FALSE); + + gs_test_init (&argc, &argv); + + /* tests go here */ + g_test_add_func ("/gnome-software/lib/utils{url}", gs_utils_url_func); + g_test_add_func ("/gnome-software/lib/utils{wilson}", gs_utils_wilson_func); + g_test_add_func ("/gnome-software/lib/utils{error}", gs_utils_error_func); + g_test_add_func ("/gnome-software/lib/utils{cache}", gs_utils_cache_func); + g_test_add_func ("/gnome-software/lib/utils{append-kv}", gs_utils_append_kv_func); + g_test_add_func ("/gnome-software/lib/os-release", gs_os_release_func); + g_test_add_func ("/gnome-software/lib/app", gs_app_func); + g_test_add_func ("/gnome-software/lib/app/progress-clamping", gs_app_progress_clamping_func); + g_test_add_func ("/gnome-software/lib/app{addons}", gs_app_addons_func); + g_test_add_func ("/gnome-software/lib/app{unique-id}", gs_app_unique_id_func); + g_test_add_data_func ("/gnome-software/lib/app{thread}", debug, gs_app_thread_func); + g_test_add_func ("/gnome-software/lib/app{list}", gs_app_list_func); + g_test_add_func ("/gnome-software/lib/app{list-wildcard-dedupe}", gs_app_list_wildcard_dedupe_func); + g_test_add_func ("/gnome-software/lib/app{list-performance}", gs_app_list_performance_func); + g_test_add_func ("/gnome-software/lib/app{list-related}", gs_app_list_related_func); + g_test_add_func ("/gnome-software/lib/plugin", gs_plugin_func); + g_test_add_func ("/gnome-software/lib/plugin{download-rewrite}", gs_plugin_download_rewrite_func); + + return g_test_run (); +} |