diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 15:18:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 15:18:46 +0000 |
commit | 56294d30a82ec2da6f9ce399740c1ef65a9ddef4 (patch) | |
tree | bbe3823e41495d026ba8edc6eeaef166edb7e2a2 /plugins/dummy | |
parent | Initial commit. (diff) | |
download | gnome-software-56294d30a82ec2da6f9ce399740c1ef65a9ddef4.tar.xz gnome-software-56294d30a82ec2da6f9ce399740c1ef65a9ddef4.zip |
Adding upstream version 3.38.1.upstream/3.38.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/dummy')
-rw-r--r-- | plugins/dummy/gs-plugin-dummy.c | 938 | ||||
-rw-r--r-- | plugins/dummy/gs-self-test.c | 898 | ||||
-rw-r--r-- | plugins/dummy/meson.build | 41 |
3 files changed, 1877 insertions, 0 deletions
diff --git a/plugins/dummy/gs-plugin-dummy.c b/plugins/dummy/gs-plugin-dummy.c new file mode 100644 index 0000000..824baae --- /dev/null +++ b/plugins/dummy/gs-plugin-dummy.c @@ -0,0 +1,938 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2011-2017 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2015-2016 Kalev Lember <klember@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> + +#include <gnome-software.h> + +/* + * SECTION: + * Provides some dummy data that is useful in self test programs. + */ + +struct GsPluginData { + guint quirk_id; + guint allow_updates_id; + gboolean allow_updates_inhibit; + GsApp *cached_origin; + GHashTable *installed_apps; /* id:1 */ + GHashTable *available_apps; /* id:1 */ +}; + +/* just flip-flop this every few seconds */ +static gboolean +gs_plugin_dummy_allow_updates_cb (gpointer user_data) +{ + GsPlugin *plugin = GS_PLUGIN (user_data); + GsPluginData *priv = gs_plugin_get_data (plugin); + gs_plugin_set_allow_updates (plugin, priv->allow_updates_inhibit); + priv->allow_updates_inhibit = !priv->allow_updates_inhibit; + return G_SOURCE_CONTINUE; +} + +void +gs_plugin_initialize (GsPlugin *plugin) +{ + GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData)); + if (g_getenv ("GS_SELF_TEST_DUMMY_ENABLE") == NULL) { + g_debug ("disabling '%s' as not in self test", + gs_plugin_get_name (plugin)); + gs_plugin_set_enabled (plugin, FALSE); + return; + } + + /* toggle this */ + if (g_getenv ("GS_SELF_TEST_TOGGLE_ALLOW_UPDATES") != NULL) { + priv->allow_updates_id = g_timeout_add_seconds (10, + gs_plugin_dummy_allow_updates_cb, plugin); + } + + /* add source */ + priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin)); + gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE); + gs_app_set_origin_hostname (priv->cached_origin, "http://www.bbc.co.uk/"); + + /* add the source to the plugin cache which allows us to match the + * unique ID to a GsApp when creating an event */ + gs_plugin_cache_add (plugin, NULL, priv->cached_origin); + + /* keep track of what apps are installed */ + priv->installed_apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + priv->available_apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_insert (priv->available_apps, + g_strdup ("chiron.desktop"), + GUINT_TO_POINTER (1)); + g_hash_table_insert (priv->available_apps, + g_strdup ("zeus.desktop"), + GUINT_TO_POINTER (1)); + g_hash_table_insert (priv->available_apps, + g_strdup ("zeus-spell.addon"), + GUINT_TO_POINTER (1)); + g_hash_table_insert (priv->available_apps, + g_strdup ("com.hughski.ColorHug2.driver"), + GUINT_TO_POINTER (1)); + + /* need help from appstream */ + gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream"); + gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "os-release"); + gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "odrs"); +} + +void +gs_plugin_destroy (GsPlugin *plugin) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + if (priv->installed_apps != NULL) + g_hash_table_unref (priv->installed_apps); + if (priv->available_apps != NULL) + g_hash_table_unref (priv->available_apps); + if (priv->quirk_id > 0) + g_source_remove (priv->quirk_id); + if (priv->cached_origin != NULL) + g_object_unref (priv->cached_origin); +} + +void +gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app) +{ + if (gs_app_get_id (app) != NULL && + g_str_has_prefix (gs_app_get_id (app), "dummy:")) { + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + return; + } + if (g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "com.hughski.ColorHug2.driver") == 0 || + g_strcmp0 (gs_app_get_id (app), "zeus-spell.addon") == 0 || + g_strcmp0 (gs_app_get_source_default (app), "chiron") == 0) + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); +} + +static gboolean +gs_plugin_dummy_delay (GsPlugin *plugin, + GsApp *app, + guint timeout_ms, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = TRUE; + guint i; + guint timeout_us = timeout_ms * 10; + + /* do blocking delay in 1% increments */ + for (i = 0; i < 100; i++) { + g_usleep (timeout_us); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { + gs_utils_error_convert_gio (error); + ret = FALSE; + break; + } + if (app != NULL) + gs_app_set_progress (app, i); + gs_plugin_status_update (plugin, app, + GS_PLUGIN_STATUS_DOWNLOADING); + } + return ret; +} + +static gboolean +gs_plugin_dummy_poll_cb (gpointer user_data) +{ + g_autoptr(GsApp) app = NULL; + GsPlugin *plugin = GS_PLUGIN (user_data); + + /* find the app in the per-plugin cache -- this assumes that we can + * calculate the same key as used when calling gs_plugin_cache_add() */ + app = gs_plugin_cache_lookup (plugin, "chiron"); + if (app == NULL) { + g_warning ("app not found in cache!"); + return FALSE; + } + + /* toggle this to animate the hide/show the 3rd party banner */ + if (!gs_app_has_quirk (app, GS_APP_QUIRK_PROVENANCE)) { + g_debug ("about to make app distro-provided"); + gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE); + } else { + g_debug ("about to make app 3rd party"); + gs_app_remove_quirk (app, GS_APP_QUIRK_PROVENANCE); + } + + /* continue polling */ + return TRUE; +} + +gboolean +gs_plugin_url_to_app (GsPlugin *plugin, + GsAppList *list, + const gchar *url, + GCancellable *cancellable, + GError **error) +{ + g_autofree gchar *path = NULL; + g_autofree gchar *scheme = NULL; + g_autoptr(GsApp) app = NULL; + + /* not us */ + scheme = gs_utils_get_url_scheme (url); + if (g_strcmp0 (scheme, "dummy") != 0) + return TRUE; + + /* create app */ + path = gs_utils_get_url_path (url); + app = gs_app_new (path); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_set_metadata (app, "GnomeSoftware::Creator", + gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + return TRUE; +} + +typedef struct { + GMainLoop *loop; + GCancellable *cancellable; + guint timer_id; + gulong cancellable_id; +} GsPluginDummyTimeoutHelper; + +static gboolean +gs_plugin_dummy_timeout_hang_cb (gpointer user_data) +{ + GsPluginDummyTimeoutHelper *helper = (GsPluginDummyTimeoutHelper *) user_data; + helper->timer_id = 0; + g_debug ("timeout hang"); + g_main_loop_quit (helper->loop); + return FALSE; +} + +static void +gs_plugin_dummy_timeout_cancelled_cb (GCancellable *cancellable, gpointer user_data) +{ + GsPluginDummyTimeoutHelper *helper = (GsPluginDummyTimeoutHelper *) user_data; + g_debug ("calling cancel"); + g_main_loop_quit (helper->loop); +} + +static void +gs_plugin_dummy_timeout_helper_free (GsPluginDummyTimeoutHelper *helper) +{ + if (helper->cancellable_id != 0) + g_signal_handler_disconnect (helper->cancellable, helper->cancellable_id); + if (helper->timer_id != 0) + g_source_remove (helper->timer_id); + if (helper->cancellable != NULL) + g_object_unref (helper->cancellable); + g_main_loop_unref (helper->loop); + g_free (helper); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GsPluginDummyTimeoutHelper, gs_plugin_dummy_timeout_helper_free) + +static void +gs_plugin_dummy_timeout_add (guint timeout_ms, GCancellable *cancellable) +{ + g_autoptr(GsPluginDummyTimeoutHelper) helper = g_new0 (GsPluginDummyTimeoutHelper, 1); + helper->loop = g_main_loop_new (NULL, TRUE); + if (cancellable != NULL) { + helper->cancellable = g_object_ref (cancellable); + helper->cancellable_id = + g_signal_connect (cancellable, "cancelled", + G_CALLBACK (gs_plugin_dummy_timeout_cancelled_cb), + helper); + } + helper->timer_id = g_timeout_add (timeout_ms, + gs_plugin_dummy_timeout_hang_cb, + helper); + g_main_loop_run (helper->loop); +} + +gboolean +gs_plugin_add_alternates (GsPlugin *plugin, + GsApp *app, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + if (g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) { + g_autoptr(GsApp) app2 = gs_app_new ("chiron.desktop"); + gs_app_list_add (list, app2); + } + return TRUE; +} + +gboolean +gs_plugin_add_search (GsPlugin *plugin, + gchar **values, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + g_autoptr(GsApp) app = NULL; + g_autoptr(AsIcon) ic = NULL; + + /* hang the plugin for 5 seconds */ + if (g_strcmp0 (values[0], "hang") == 0) { + gs_plugin_dummy_timeout_add (5000, cancellable); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { + gs_utils_error_convert_gio (error); + return FALSE; + } + return TRUE; + } + + /* we're very specific */ + if (g_strcmp0 (values[0], "chiron") != 0) + return TRUE; + + /* does the app already exist? */ + app = gs_plugin_cache_lookup (plugin, "chiron"); + if (app != NULL) { + g_debug ("using %s fom the cache", gs_app_get_id (app)); + gs_app_list_add (list, app); + return TRUE; + } + + /* set up a timeout to emulate getting a GFileMonitor callback */ + priv->quirk_id = + g_timeout_add_seconds (1, gs_plugin_dummy_poll_cb, plugin); + + /* use a generic stock icon */ + ic = as_icon_new (); + as_icon_set_kind (ic, AS_ICON_KIND_STOCK); + as_icon_set_name (ic, "drive-harddisk"); + + /* add a live updatable normal application */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A teaching application"); + gs_app_add_icon (app, ic); + gs_app_set_size_installed (app, 42 * 1024 * 1024); + gs_app_set_size_download (app, 50 * 1024 * 1024); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_set_metadata (app, "GnomeSoftware::Creator", + gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + + /* add to cache so it can be found by the flashing callback */ + gs_plugin_cache_add (plugin, NULL, app); + + return TRUE; +} + +gboolean +gs_plugin_add_updates (GsPlugin *plugin, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + GsApp *app; + GsApp *proxy; + g_autoptr(AsIcon) ic = NULL; + + /* update UI as this might take some time */ + gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING); + + /* spin */ + if (!gs_plugin_dummy_delay (plugin, NULL, 2000, cancellable, error)) + return FALSE; + + /* use a generic stock icon */ + ic = as_icon_new (); + as_icon_set_kind (ic, AS_ICON_KIND_STOCK); + as_icon_set_name (ic, "drive-harddisk"); + + /* add a live updatable normal application */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A teaching application"); + gs_app_set_update_details (app, "Do not crash when using libvirt."); + gs_app_set_update_urgency (app, AS_URGENCY_KIND_HIGH); + gs_app_add_icon (app, ic); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + g_object_unref (app); + + /* add a offline OS update */ + app = gs_app_new (NULL); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "libvirt-glib-devel"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Development files for libvirt"); + gs_app_set_update_details (app, "Fix several memory leaks."); + gs_app_set_update_urgency (app, AS_URGENCY_KIND_LOW); + gs_app_set_kind (app, AS_APP_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); + gs_app_set_state (app, AS_APP_STATE_UPDATABLE); + gs_app_add_source (app, "libvirt-glib-devel"); + gs_app_add_source_id (app, "libvirt-glib-devel;0.0.1;noarch;fedora"); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + g_object_unref (app); + + /* add a live OS update */ + app = gs_app_new (NULL); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "chiron-libs"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "library for chiron"); + gs_app_set_update_details (app, "Do not crash when using libvirt."); + gs_app_set_update_urgency (app, AS_URGENCY_KIND_HIGH); + gs_app_set_kind (app, AS_APP_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); + gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); + gs_app_add_source (app, "chiron-libs"); + gs_app_add_source_id (app, "chiron-libs;0.0.1;i386;updates-testing"); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + g_object_unref (app); + + /* add a proxy app update */ + proxy = gs_app_new ("proxy.desktop"); + gs_app_set_name (proxy, GS_APP_QUALITY_NORMAL, "Proxy"); + gs_app_set_summary (proxy, GS_APP_QUALITY_NORMAL, "A proxy app"); + gs_app_set_update_details (proxy, "Update all related apps."); + gs_app_set_update_urgency (proxy, AS_URGENCY_KIND_HIGH); + gs_app_add_icon (proxy, ic); + gs_app_set_kind (proxy, AS_APP_KIND_DESKTOP); + gs_app_add_quirk (proxy, GS_APP_QUIRK_IS_PROXY); + gs_app_set_state (proxy, AS_APP_STATE_UPDATABLE_LIVE); + gs_app_set_management_plugin (proxy, gs_plugin_get_name (plugin)); + gs_app_list_add (list, proxy); + g_object_unref (proxy); + + /* add a proxy related app */ + app = gs_app_new ("proxy-related-app.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Related app"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A related app"); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_add_related (proxy, app); + g_object_unref (app); + + /* add another proxy related app */ + app = gs_app_new ("proxy-another-related-app.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Another Related app"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A related app"); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_add_related (proxy, app); + g_object_unref (app); + + return TRUE; +} + +gboolean +gs_plugin_add_installed (GsPlugin *plugin, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + const gchar *packages[] = { "zeus", "zeus-common", NULL }; + const gchar *app_ids[] = { "Uninstall Zeus.desktop", NULL }; + guint i; + + /* add all packages */ + for (i = 0; packages[i] != NULL; i++) { + g_autoptr(GsApp) app = gs_app_new (NULL); + gs_app_add_source (app, packages[i]); + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + gs_app_set_kind (app, AS_APP_KIND_GENERIC); + gs_app_set_origin (app, "london-west"); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + } + + /* add all app-ids */ + for (i = 0; app_ids[i] != NULL; i++) { + g_autoptr(GsApp) app = gs_app_new (app_ids[i]); + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + } + + return TRUE; +} + +gboolean +gs_plugin_add_popular (GsPlugin *plugin, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GsApp) app1 = NULL; + g_autoptr(GsApp) app2 = NULL; + + /* add wildcard */ + app1 = gs_app_new ("zeus.desktop"); + gs_app_add_quirk (app1, GS_APP_QUIRK_IS_WILDCARD); + gs_app_set_metadata (app1, "GnomeSoftware::Creator", + gs_plugin_get_name (plugin)); + gs_app_list_add (list, app1); + + /* add again, this time with a prefix so it gets deduplicated */ + app2 = gs_app_new ("zeus.desktop"); + gs_app_set_scope (app2, AS_APP_SCOPE_USER); + gs_app_set_bundle_kind (app2, AS_BUNDLE_KIND_SNAP); + gs_app_set_metadata (app2, "GnomeSoftware::Creator", + gs_plugin_get_name (plugin)); + gs_app_list_add (list, app2); + return TRUE; +} + +gboolean +gs_plugin_app_remove (GsPlugin *plugin, + GsApp *app, + GCancellable *cancellable, + GError **error) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + + /* only process this app if was created by this plugin */ + if (g_strcmp0 (gs_app_get_management_plugin (app), + gs_plugin_get_name (plugin)) != 0) + return TRUE; + + /* remove app */ + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0) { + gs_app_set_state (app, AS_APP_STATE_REMOVING); + if (!gs_plugin_dummy_delay (plugin, app, 500, cancellable, error)) { + gs_app_set_state_recover (app); + return FALSE; + } + gs_app_set_state (app, AS_APP_STATE_UNKNOWN); + } + + /* keep track */ + g_hash_table_remove (priv->installed_apps, gs_app_get_id (app)); + g_hash_table_insert (priv->available_apps, + g_strdup (gs_app_get_id (app)), + GUINT_TO_POINTER (1)); + return TRUE; +} + +gboolean +gs_plugin_app_install (GsPlugin *plugin, + GsApp *app, + GCancellable *cancellable, + GError **error) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + + /* only process this app if was created by this plugin */ + if (g_strcmp0 (gs_app_get_management_plugin (app), + gs_plugin_get_name (plugin)) != 0) + return TRUE; + + /* install app */ + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) { + gs_app_set_state (app, AS_APP_STATE_INSTALLING); + if (!gs_plugin_dummy_delay (plugin, app, 500, cancellable, error)) { + gs_app_set_state_recover (app); + return FALSE; + } + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + } + + /* keep track */ + g_hash_table_insert (priv->installed_apps, + g_strdup (gs_app_get_id (app)), + GUINT_TO_POINTER (1)); + g_hash_table_remove (priv->available_apps, gs_app_get_id (app)); + + return TRUE; +} + +gboolean +gs_plugin_update_app (GsPlugin *plugin, + GsApp *app, + GCancellable *cancellable, + GError **error) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + + /* only process this app if was created by this plugin */ + if (g_strcmp0 (gs_app_get_management_plugin (app), + gs_plugin_get_name (plugin)) != 0) + return TRUE; + + if (!g_str_has_prefix (gs_app_get_id (app), "proxy")) { + /* always fail */ + g_set_error_literal (error, + GS_PLUGIN_ERROR, + GS_PLUGIN_ERROR_DOWNLOAD_FAILED, + "no network connection is available"); + gs_utils_error_add_origin_id (error, priv->cached_origin); + return FALSE; + } + + /* simulate an update for 4 seconds */ + gs_app_set_state (app, AS_APP_STATE_INSTALLING); + for (guint i = 1; i <= 4; ++i) { + gs_app_set_progress (app, 25 * i); + sleep (1); + } + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + + return TRUE; +} + +static gboolean +refine_app (GsPlugin *plugin, + GsApp *app, + GsPluginRefineFlags flags, + GCancellable *cancellable, + GError **error) +{ + GsPluginData *priv = gs_plugin_get_data (plugin); + + /* make the local system EOL */ + if (gs_app_get_metadata_item (app, "GnomeSoftware::CpeName") != NULL) + gs_app_set_state (app, AS_APP_STATE_UNAVAILABLE); + + /* state */ + if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) { + if (g_hash_table_lookup (priv->installed_apps, + gs_app_get_id (app)) != NULL) + gs_app_set_state (app, AS_APP_STATE_INSTALLED); + if (g_hash_table_lookup (priv->available_apps, + gs_app_get_id (app)) != NULL) + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + } + + /* kind */ + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "com.hughski.ColorHug2.driver") == 0 || + g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) { + if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN) + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + } + + /* license */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE) { + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 || + g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) + gs_app_set_license (app, GS_APP_QUALITY_HIGHEST, "GPL-2.0+"); + } + + /* homepage */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL) { + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0) { + gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, + "http://www.test.org/"); + } + } + + /* origin */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) { + if (g_strcmp0 (gs_app_get_id (app), "zeus-spell.addon") == 0) + gs_app_set_origin (app, "london-east"); + } + + /* default */ + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0) { + if (gs_app_get_name (app) == NULL) + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "tmp"); + if (gs_app_get_summary (app) == NULL) + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "tmp"); + if (gs_app_get_icons(app)->len == 0) { + g_autoptr(AsIcon) ic = NULL; + ic = as_icon_new (); + as_icon_set_kind (ic, AS_ICON_KIND_STOCK); + as_icon_set_name (ic, "drive-harddisk"); + gs_app_add_icon (app, ic); + } + } + + /* description */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION) { + if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0) { + gs_app_set_description (app, GS_APP_QUALITY_NORMAL, + "long description!"); + } + } + + /* add fake review */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS) { + g_autoptr(AsReview) review1 = NULL; + g_autoptr(AsReview) review2 = NULL; + g_autoptr(GDateTime) dt = NULL; + + dt = g_date_time_new_now_utc (); + + /* set first review */ + review1 = as_review_new (); + as_review_set_rating (review1, 50); + as_review_set_reviewer_name (review1, "Angela Avery"); + as_review_set_summary (review1, "Steep learning curve, but worth it"); + as_review_set_description (review1, "Best overall 3D application I've ever used overall 3D application I've ever used. Best overall 3D application I've ever used overall 3D application I've ever used. Best overall 3D application I've ever used overall 3D application I've ever used. Best overall 3D application I've ever used overall 3D application I've ever used."); + as_review_set_version (review1, "3.16.4"); + as_review_set_date (review1, dt); + gs_app_add_review (app, review1); + + /* set self review */ + review2 = as_review_new (); + as_review_set_rating (review2, 100); + as_review_set_reviewer_name (review2, "Just Myself"); + as_review_set_summary (review2, "I like this application"); + as_review_set_description (review2, "I'm not very wordy myself."); + as_review_set_version (review2, "3.16.3"); + as_review_set_date (review2, dt); + as_review_set_flags (review2, AS_REVIEW_FLAG_SELF); + gs_app_add_review (app, review2); + } + + /* add fake ratings */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS) { + g_autoptr(GArray) ratings = NULL; + const gint data[] = { 0, 10, 20, 30, 15, 2 }; + ratings = g_array_sized_new (FALSE, FALSE, sizeof (gint), 6); + g_array_append_vals (ratings, data, 6); + gs_app_set_review_ratings (app, ratings); + } + + /* add a rating */ + if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING) { + gs_app_set_rating (app, 66); + } + + return TRUE; +} + +gboolean +gs_plugin_refine (GsPlugin *plugin, + GsAppList *list, + GsPluginRefineFlags flags, + GCancellable *cancellable, + GError **error) +{ + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); + + if (!refine_app (plugin, app, flags, cancellable, error)) + return FALSE; + } + + return TRUE; +} + +gboolean +gs_plugin_add_category_apps (GsPlugin *plugin, + GsCategory *category, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GsApp) app = gs_app_new ("chiron.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines"); + gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org"); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/apps/chiron.desktop.png", NULL)); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + return TRUE; +} + +gboolean +gs_plugin_add_recent (GsPlugin *plugin, + GsAppList *list, + guint64 age, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GsApp) app = gs_app_new ("chiron.desktop"); + gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines"); + gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org"); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/apps/chiron.desktop.png", NULL)); + gs_app_set_kind (app, AS_APP_KIND_DESKTOP); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_list_add (list, app); + return TRUE; +} + +gboolean +gs_plugin_add_distro_upgrades (GsPlugin *plugin, + GsAppList *list, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GsApp) app = NULL; + g_autoptr(AsIcon) ic = NULL; + + /* use stock icon */ + ic = as_icon_new (); + as_icon_set_kind (ic, AS_ICON_KIND_STOCK); + as_icon_set_name (ic, "application-x-addon"); + + /* get existing item from the cache */ + app = gs_plugin_cache_lookup (plugin, "user/*/*/os-upgrade/org.fedoraproject.release-rawhide.upgrade/*"); + if (app != NULL) { + gs_app_list_add (list, app); + return TRUE; + } + + app = gs_app_new ("org.fedoraproject.release-rawhide.upgrade"); + gs_app_set_scope (app, AS_APP_SCOPE_USER); + gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + gs_app_set_name (app, GS_APP_QUALITY_LOWEST, "Fedora"); + gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, + "A major upgrade, with new features and added polish."); + gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, + "https://fedoraproject.org/wiki/Releases/24/Schedule"); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE); + gs_app_add_quirk (app, GS_APP_QUIRK_NOT_REVIEWABLE); + gs_app_set_version (app, "25"); + gs_app_set_size_installed (app, 256 * 1024 * 1024); + gs_app_set_size_download (app, 1024 * 1024 * 1024); + gs_app_set_license (app, GS_APP_QUALITY_LOWEST, "LicenseRef-free"); + gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); + gs_app_set_metadata (app, "GnomeSoftware::UpgradeBanner-css", + "background: url('" DATADIR "/gnome-software/upgrade-bg.png');" + "background-size: 100% 100%;"); + gs_app_add_icon (app, ic); + gs_app_list_add (list, app); + + gs_plugin_cache_add (plugin, NULL, app); + + return TRUE; +} + +gboolean +gs_plugin_download_app (GsPlugin *plugin, + GsApp *app, + GCancellable *cancellable, + GError **error) +{ + return gs_plugin_dummy_delay (plugin, app, 5100, cancellable, error); +} + +gboolean +gs_plugin_refresh (GsPlugin *plugin, + guint cache_age, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GsApp) app = gs_app_new (NULL); + return gs_plugin_dummy_delay (plugin, app, 3100, cancellable, error); +} + +gboolean +gs_plugin_app_upgrade_download (GsPlugin *plugin, GsApp *app, + GCancellable *cancellable, GError **error) +{ + /* only process this app if was created by this plugin */ + if (g_strcmp0 (gs_app_get_management_plugin (app), + gs_plugin_get_name (plugin)) != 0) + return TRUE; + + g_debug ("starting download"); + gs_app_set_state (app, AS_APP_STATE_INSTALLING); + if (!gs_plugin_dummy_delay (plugin, app, 5000, cancellable, error)) { + gs_app_set_state_recover (app); + return FALSE; + } + gs_app_set_state (app, AS_APP_STATE_UPDATABLE); + return TRUE; +} + +gboolean +gs_plugin_app_upgrade_trigger (GsPlugin *plugin, GsApp *app, + GCancellable *cancellable, GError **error) +{ + /* only process this app if was created by this plugin */ + if (g_strcmp0 (gs_app_get_management_plugin (app), + gs_plugin_get_name (plugin)) != 0) + return TRUE; + + /* NOP */ + return TRUE; +} + +gboolean +gs_plugin_update_cancel (GsPlugin *plugin, GsApp *app, + GCancellable *cancellable, GError **error) +{ + return TRUE; +} + +gboolean +gs_plugin_review_submit (GsPlugin *plugin, + GsApp *app, + AsReview *review, + GCancellable *cancellable, + GError **error) +{ + g_debug ("Submitting dummy review"); + return TRUE; +} + +gboolean +gs_plugin_review_report (GsPlugin *plugin, + GsApp *app, + AsReview *review, + GCancellable *cancellable, + GError **error) +{ + g_debug ("Reporting dummy review"); + as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); + return TRUE; +} + +gboolean +gs_plugin_review_upvote (GsPlugin *plugin, + GsApp *app, + AsReview *review, + GCancellable *cancellable, + GError **error) +{ + g_debug ("Upvoting dummy review"); + as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); + return TRUE; +} + +gboolean +gs_plugin_review_downvote (GsPlugin *plugin, + GsApp *app, + AsReview *review, + GCancellable *cancellable, + GError **error) +{ + g_debug ("Downvoting dummy review"); + as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); + return TRUE; +} + +gboolean +gs_plugin_review_remove (GsPlugin *plugin, + GsApp *app, + AsReview *review, + GCancellable *cancellable, + GError **error) +{ + /* all okay */ + g_debug ("Removing dummy self-review"); + return TRUE; +} diff --git a/plugins/dummy/gs-self-test.c b/plugins/dummy/gs-self-test.c new file mode 100644 index 0000000..30360cc --- /dev/null +++ b/plugins/dummy/gs-self-test.c @@ -0,0 +1,898 @@ +/* -*- 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> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include <glib/gstdio.h> + +#include "gnome-software-private.h" + +#include "gs-test.h" + +static guint _status_changed_cnt = 0; + +typedef struct { + GError *error; + GMainLoop *loop; +} GsDummyTestHelper; + +static GsDummyTestHelper * +gs_dummy_test_helper_new (void) +{ + return g_new0 (GsDummyTestHelper, 1); +} + +static void +gs_dummy_test_helper_free (GsDummyTestHelper *helper) +{ + if (helper->error != NULL) + g_error_free (helper->error); + if (helper->loop != NULL) + g_main_loop_unref (helper->loop); + g_free (helper); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GsDummyTestHelper, gs_dummy_test_helper_free) + +static void +gs_plugin_loader_status_changed_cb (GsPluginLoader *plugin_loader, + GsApp *app, + GsPluginStatus status, + gpointer user_data) +{ + _status_changed_cnt++; +} + +static void +gs_plugins_dummy_install_func (GsPluginLoader *plugin_loader) +{ + gboolean ret; + g_autoptr(GsApp) app = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + g_autoptr(GError) error = NULL; + + /* install */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_management_plugin (app, "dummy"); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL, + "app", app, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED); + + /* remove */ + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REMOVE, + "app", app, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE); +} + +static void +gs_plugins_dummy_error_func (GsPluginLoader *plugin_loader) +{ + const GError *app_error; + gboolean ret; + g_autoptr(GError) error = NULL; + g_autoptr(GPtrArray) events = NULL; + g_autoptr(GsApp) app = NULL; + g_autoptr(GsPluginEvent) event = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* drop all caches */ + gs_utils_rmtree (g_getenv ("GS_SELF_TEST_CACHEDIR"), NULL); + gs_plugin_loader_setup_again (plugin_loader); + + /* update, which should cause an error to be emitted */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_management_plugin (app, "dummy"); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPDATE, + "app", app, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + + /* get last active event */ + event = gs_plugin_loader_get_event_default (plugin_loader); + g_assert (event != NULL); + g_assert (gs_plugin_event_get_app (event) == app); + + /* check all the events */ + events = gs_plugin_loader_get_events (plugin_loader); + g_assert_cmpint (events->len, ==, 1); + event = g_ptr_array_index (events, 0); + g_assert (gs_plugin_event_get_app (event) == app); + app_error = gs_plugin_event_get_error (event); + g_assert (app_error != NULL); + g_assert_error (app_error, + GS_PLUGIN_ERROR, + GS_PLUGIN_ERROR_DOWNLOAD_FAILED); +} + +static void +gs_plugins_dummy_refine_func (GsPluginLoader *plugin_loader) +{ + gboolean ret; + g_autoptr(GsApp) app = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get the extra bits */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_management_plugin (app, "dummy"); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpstr (gs_app_get_license (app), ==, "GPL-2.0+"); + g_assert_cmpstr (gs_app_get_description (app), !=, NULL); + g_assert_cmpstr (gs_app_get_url (app, AS_URL_KIND_HOMEPAGE), ==, "http://www.test.org/"); +} + +static void +gs_plugins_dummy_metadata_quirks (GsPluginLoader *plugin_loader) +{ + gboolean ret; + g_autoptr(GsApp) app = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get the extra bits */ + app = gs_app_new ("chiron.desktop"); + gs_app_set_management_plugin (app, "dummy"); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpstr (gs_app_get_description (app), !=, NULL); + + /* check the not-launchable quirk */ + + g_assert (!gs_app_has_quirk(app, GS_APP_QUIRK_NOT_LAUNCHABLE)); + + gs_app_set_metadata (app, "GnomeSoftware::quirks::not-launchable", "true"); + + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + + g_assert (gs_app_has_quirk(app, GS_APP_QUIRK_NOT_LAUNCHABLE)); + + gs_app_set_metadata (app, "GnomeSoftware::quirks::not-launchable", NULL); + gs_app_set_metadata (app, "GnomeSoftware::quirks::not-launchable", "false"); + + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + + g_assert (!gs_app_has_quirk(app, GS_APP_QUIRK_NOT_LAUNCHABLE)); +} + +static void +gs_plugins_dummy_key_colors_func (GsPluginLoader *plugin_loader) +{ + GPtrArray *array; + gboolean ret; + guint i; + g_autoptr(GsApp) app = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + g_autoptr(GError) error = NULL; + + /* get the extra bits */ + app = gs_app_new ("zeus.desktop"); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_KEY_COLORS, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + array = gs_app_get_key_colors (app); + g_assert_cmpint (array->len, >=, 3); + + /* check values are in range */ + for (i = 0; i < array->len; i++) { + GdkRGBA *kc = g_ptr_array_index (array, i); + g_assert_cmpfloat (kc->red, >=, 0.f); + g_assert_cmpfloat (kc->red, <=, 1.f); + g_assert_cmpfloat (kc->green, >=, 0.f); + g_assert_cmpfloat (kc->green, <=, 1.f); + g_assert_cmpfloat (kc->blue, >=, 0.f); + g_assert_cmpfloat (kc->blue, <=, 1.f); + g_assert_cmpfloat (kc->alpha, >=, 0.f); + g_assert_cmpfloat (kc->alpha, <=, 1.f); + } +} + +static void +gs_plugins_dummy_updates_func (GsPluginLoader *plugin_loader) +{ + GsApp *app; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get the updates list */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_UPDATES, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_UPDATE_DETAILS, + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list != NULL); + + /* make sure there are three entries */ + g_assert_cmpint (gs_app_list_length (list), ==, 3); + app = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app), ==, "chiron.desktop"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE_LIVE); + g_assert_cmpstr (gs_app_get_update_details (app), ==, "Do not crash when using libvirt."); + g_assert_cmpint (gs_app_get_update_urgency (app), ==, AS_URGENCY_KIND_HIGH); + + /* get the virtual non-apps OS update */ + app = gs_app_list_index (list, 2); + g_assert_cmpstr (gs_app_get_id (app), ==, "org.gnome.Software.OsUpdate"); + g_assert_cmpstr (gs_app_get_name (app), ==, "OS Updates"); + g_assert_cmpstr (gs_app_get_summary (app), ==, "Includes performance, stability and security improvements."); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_OS_UPDATE); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE); + g_assert_cmpint (gs_app_list_length (gs_app_get_related (app)), ==, 2); + + /* get the virtual non-apps OS update */ + app = gs_app_list_index (list, 1); + g_assert_cmpstr (gs_app_get_id (app), ==, "proxy.desktop"); + g_assert (gs_app_has_quirk (app, GS_APP_QUIRK_IS_PROXY)); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE_LIVE); + g_assert_cmpint (gs_app_list_length (gs_app_get_related (app)), ==, 2); +} + +static void +gs_plugins_dummy_distro_upgrades_func (GsPluginLoader *plugin_loader) +{ + GsApp *app; + gboolean ret; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get the updates list */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_DISTRO_UPDATES, NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list != NULL); + + /* make sure there is one entry */ + g_assert_cmpint (gs_app_list_length (list), ==, 1); + app = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app), ==, "org.fedoraproject.release-rawhide.upgrade"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_OS_UPGRADE); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE); + + /* this should be set with a higher priority by AppStream */ + g_assert_cmpstr (gs_app_get_summary (app), ==, "Release specific tagline"); + + /* download the update */ + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPGRADE_DOWNLOAD, + "app", app, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE); + + /* trigger the update */ + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPGRADE_TRIGGER, + "app", app, + NULL); + ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE); +} + +static void +gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader) +{ + GsApp *app; + GsApp *addon; + GsAppList *addons; + g_autofree gchar *menu_path = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get installed packages */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_INSTALLED, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_ADDONS | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_KUDOS | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_MENU_PATH | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_CATEGORIES | + GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE, + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list != NULL); + + /* make sure there is one entry */ + g_assert_cmpint (gs_app_list_length (list), ==, 1); + app = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app), ==, "zeus.desktop"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP); + g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED); + g_assert_cmpstr (gs_app_get_name (app), ==, "Zeus"); + g_assert_cmpstr (gs_app_get_source_default (app), ==, "zeus"); + g_assert (gs_app_get_pixbuf (app) != NULL); + + /* check various bitfields */ + g_assert (gs_app_has_quirk (app, GS_APP_QUIRK_PROVENANCE)); + g_assert_cmpstr (gs_app_get_license (app), ==, "GPL-2.0+"); + g_assert (gs_app_get_license_is_free (app)); + + /* check kudos */ + g_assert_true (gs_app_has_kudo (app, GS_APP_KUDO_MY_LANGUAGE)); + + /* check categories */ + g_assert (gs_app_has_category (app, "Player")); + g_assert (gs_app_has_category (app, "AudioVideo")); + g_assert (!gs_app_has_category (app, "ImageProcessing")); + g_assert (gs_app_get_menu_path (app) != NULL); + menu_path = g_strjoinv ("->", gs_app_get_menu_path (app)); + g_assert_cmpstr (menu_path, ==, "Audio & Video->Music Players"); + + /* check addon */ + addons = gs_app_get_addons (app); + g_assert_cmpint (gs_app_list_length (addons), ==, 1); + addon = gs_app_list_index (addons, 0); + g_assert_cmpstr (gs_app_get_id (addon), ==, "zeus-spell.addon"); + g_assert_cmpint (gs_app_get_kind (addon), ==, AS_APP_KIND_ADDON); + g_assert_cmpint (gs_app_get_state (addon), ==, AS_APP_STATE_AVAILABLE); + g_assert_cmpstr (gs_app_get_name (addon), ==, "Spell Check"); + g_assert_cmpstr (gs_app_get_source_default (addon), ==, "zeus-spell"); + g_assert_cmpstr (gs_app_get_license (addon), ==, + "LicenseRef-free=https://www.debian.org/"); + g_assert (gs_app_get_pixbuf (addon) == NULL); +} + +static void +gs_plugins_dummy_search_func (GsPluginLoader *plugin_loader) +{ + GsApp *app; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get search result based on addon keyword */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_SEARCH, + "search", "zeus", + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON, + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list != NULL); + + /* make sure there is one entry, the parent app */ + g_assert_cmpint (gs_app_list_length (list), ==, 1); + app = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app), ==, "zeus.desktop"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP); +} + +static void +gs_plugins_dummy_search_alternate_func (GsPluginLoader *plugin_loader) +{ + GsApp *app_tmp; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsApp) app = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get search result based on addon keyword */ + app = gs_app_new ("zeus.desktop"); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_ALTERNATES, + "app", app, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON, + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list != NULL); + + /* make sure there is the original app, and the alternate */ + g_assert_cmpint (gs_app_list_length (list), ==, 2); + app_tmp = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app_tmp), ==, "chiron.desktop"); + g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_APP_KIND_DESKTOP); + app_tmp = gs_app_list_index (list, 1); + g_assert_cmpstr (gs_app_get_id (app_tmp), ==, "zeus.desktop"); + g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_APP_KIND_DESKTOP); +} + +static void +gs_plugins_dummy_hang_func (GsPluginLoader *plugin_loader) +{ + g_autoptr(GCancellable) cancellable = g_cancellable_new (); + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* drop all caches */ + gs_utils_rmtree (g_getenv ("GS_SELF_TEST_CACHEDIR"), NULL); + gs_plugin_loader_setup_again (plugin_loader); + + /* get search result based on addon keyword */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_SEARCH, + "search", "hang", + "timeout", 1, /* seconds */ + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, cancellable, &error); + gs_test_flush_main_context (); + g_assert_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_TIMED_OUT); + g_assert (list == NULL); +} + +static void +gs_plugins_dummy_search_invalid_func (GsPluginLoader *plugin_loader) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* get search result based on addon keyword */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_SEARCH, + "search", "X", + NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED); + g_assert (list == NULL); +} + +static void +gs_plugins_dummy_url_to_app_func (GsPluginLoader *plugin_loader) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GsApp) app = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_URL_TO_APP, + "search", "dummy://chiron.desktop", + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON, + NULL); + app = gs_plugin_loader_job_process_app (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (app != NULL); + g_assert_cmpstr (gs_app_get_id (app), ==, "chiron.desktop"); + g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP); +} + +static void +gs_plugins_dummy_plugin_cache_func (GsPluginLoader *plugin_loader) +{ + GsApp *app1; + GsApp *app2; + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list1 = NULL; + g_autoptr(GsAppList) list2 = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* ensure we get the same results back from calling the methods twice */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_DISTRO_UPDATES, NULL); + list1 = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list1 != NULL); + g_assert_cmpint (gs_app_list_length (list1), ==, 1); + app1 = gs_app_list_index (list1, 0); + + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_DISTRO_UPDATES, NULL); + list2 = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list2 != NULL); + g_assert_cmpint (gs_app_list_length (list2), ==, 1); + app2 = gs_app_list_index (list2, 0); + + /* make sure there is one GObject */ + g_assert_cmpstr (gs_app_get_id (app1), ==, gs_app_get_id (app2)); + g_assert (app1 == app2); +} + +static void +gs_plugins_dummy_wildcard_func (GsPluginLoader *plugin_loader) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GsAppList) list1 = NULL; + g_autoptr(GsAppList) list2 = NULL; + const gchar *popular_override = "chiron.desktop,zeus.desktop"; + g_auto(GStrv) apps = NULL; + g_autoptr(GsPluginJob) plugin_job = NULL; + + /* use the plugin's add_popular function */ + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_POPULAR, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON, + NULL); + list1 = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list1 != NULL); + g_assert_cmpint (gs_app_list_length (list1), ==, 1); + + /* override the popular list (do not use the add_popular function) */ + g_setenv ("GNOME_SOFTWARE_POPULAR", popular_override, TRUE); + g_object_unref (plugin_job); + plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_POPULAR, + "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON, + NULL); + list2 = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); + gs_test_flush_main_context (); + g_assert_no_error (error); + g_assert (list2 != NULL); + + apps = g_strsplit (popular_override, ",", 0); + g_assert_cmpint (gs_app_list_length (list2), ==, g_strv_length (apps)); + + for (guint i = 0; i < gs_app_list_length (list2); ++i) { + GsApp *app = gs_app_list_index (list2, i); + g_assert (g_strv_contains ((const gchar * const *) apps, gs_app_get_id (app))); + } +} + +static void +plugin_job_action_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source); + GsDummyTestHelper *helper = (GsDummyTestHelper *) user_data; + + gs_plugin_loader_job_action_finish (plugin_loader, res, &helper->error); + if (helper->loop != NULL) + g_main_loop_quit (helper->loop); +} + +static void +gs_plugins_dummy_limit_parallel_ops_func (GsPluginLoader *plugin_loader) +{ + g_autoptr(GsAppList) list = NULL; + GsApp *app1 = NULL; + g_autoptr(GsApp) app2 = NULL; + g_autoptr(GsApp) app3 = NULL; + g_autoptr(GsPluginJob) plugin_job1 = NULL; + g_autoptr(GsPluginJob) plugin_job2 = NULL; + g_autoptr(GsPluginJob) plugin_job3 = NULL; + g_autoptr(GMainContext) context = NULL; + g_autoptr(GsDummyTestHelper) helper1 = gs_dummy_test_helper_new (); + g_autoptr(GsDummyTestHelper) helper2 = gs_dummy_test_helper_new (); + g_autoptr(GsDummyTestHelper) helper3 = gs_dummy_test_helper_new (); + + /* drop all caches */ + gs_utils_rmtree (g_getenv ("GS_SELF_TEST_CACHEDIR"), NULL); + gs_plugin_loader_setup_again (plugin_loader); + + /* get the updates list */ + plugin_job1 = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_DISTRO_UPDATES, NULL); + list = gs_plugin_loader_job_process (plugin_loader, plugin_job1, NULL, &helper3->error); + gs_test_flush_main_context (); + g_assert_no_error (helper3->error); + g_assert (list != NULL); + g_assert_cmpint (gs_app_list_length (list), ==, 1); + app1 = gs_app_list_index (list, 0); + g_assert_cmpstr (gs_app_get_id (app1), ==, "org.fedoraproject.release-rawhide.upgrade"); + g_assert_cmpint (gs_app_get_kind (app1), ==, AS_APP_KIND_OS_UPGRADE); + g_assert_cmpint (gs_app_get_state (app1), ==, AS_APP_STATE_AVAILABLE); + + /* allow only one operation at a time */ + gs_plugin_loader_set_max_parallel_ops (plugin_loader, 1); + + app2 = gs_app_new ("chiron.desktop"); + gs_app_set_management_plugin (app2, "dummy"); + gs_app_set_state (app2, AS_APP_STATE_AVAILABLE); + + /* use "proxy" prefix so the update function succeeds... */ + app3 = gs_app_new ("proxy-zeus.desktop"); + gs_app_set_management_plugin (app3, "dummy"); + gs_app_set_state (app3, AS_APP_STATE_UPDATABLE_LIVE); + + context = g_main_context_new (); + helper3->loop = g_main_loop_new (context, FALSE); + g_main_context_push_thread_default (context); + + /* call a few operations at the "same time" */ + + /* download an upgrade */ + g_object_unref (plugin_job1); + plugin_job1 = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPGRADE_DOWNLOAD, + "app", app1, + NULL); + gs_plugin_loader_job_process_async (plugin_loader, + plugin_job1, + NULL, + plugin_job_action_cb, + helper1); + + /* install an app */ + plugin_job2 = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL, + "app", app2, + NULL); + gs_plugin_loader_job_process_async (plugin_loader, + plugin_job2, + NULL, + plugin_job_action_cb, + helper2); + + /* update an app */ + plugin_job3 = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPDATE, + "app", app3, + NULL); + gs_plugin_loader_job_process_async (plugin_loader, + plugin_job3, + NULL, + plugin_job_action_cb, + helper3); + + /* since we have only 1 parallel installation op possible, + * verify the last operations are pending */ + g_assert_cmpint (gs_app_get_state (app2), ==, AS_APP_STATE_AVAILABLE); + g_assert_cmpint (gs_app_get_pending_action (app2), ==, GS_PLUGIN_ACTION_INSTALL); + g_assert_cmpint (gs_app_get_state (app3), ==, AS_APP_STATE_UPDATABLE_LIVE); + g_assert_cmpint (gs_app_get_pending_action (app3), ==, GS_PLUGIN_ACTION_UPDATE); + + /* wait for the 2nd installation to finish, it means the 1st should have been + * finished too */ + g_main_loop_run (helper3->loop); + g_main_context_pop_thread_default (context); + + gs_test_flush_main_context (); + g_assert_no_error (helper1->error); + g_assert_no_error (helper2->error); + g_assert_no_error (helper3->error); + + g_assert_cmpint (gs_app_get_state (app1), ==, AS_APP_STATE_UPDATABLE); + g_assert_cmpint (gs_app_get_state (app2), ==, AS_APP_STATE_INSTALLED); + g_assert_cmpint (gs_app_get_state (app3), ==, AS_APP_STATE_INSTALLED); + + /* set the default max parallel ops */ + gs_plugin_loader_set_max_parallel_ops (plugin_loader, 0); +} + +int +main (int argc, char **argv) +{ + g_autofree gchar *tmp_root = NULL; + gboolean ret; + int retval; + g_autofree gchar *xml = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GsPluginLoader) plugin_loader = NULL; + const gchar *allowlist[] = { + "appstream", + "dummy", + "generic-updates", + "hardcoded-blocklist", + "desktop-categories", + "desktop-menu-path", + "icons", + "key-colors", + "provenance", + "provenance-license", + NULL + }; + + /* While we use %G_TEST_OPTION_ISOLATE_DIRS to create temporary directories + * for each of the tests, we want to use the system MIME registry, assuming + * that it exists and correctly has shared-mime-info installed. */ +#if GLIB_CHECK_VERSION(2, 60, 0) + g_content_type_set_mime_dirs (NULL); +#endif + + /* Similarly, add the system-wide icon theme path before it’s + * overwritten by %G_TEST_OPTION_ISOLATE_DIRS. */ + gs_test_expose_icon_theme_paths (); + + g_test_init (&argc, &argv, +#if GLIB_CHECK_VERSION(2, 60, 0) + G_TEST_OPTION_ISOLATE_DIRS, +#endif + NULL); + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + g_setenv ("GS_XMLB_VERBOSE", "1", TRUE); + + /* set all the things required as a dummy test harness */ + g_setenv ("GS_SELF_TEST_LOCALE", "en_GB", TRUE); + g_setenv ("GS_SELF_TEST_DUMMY_ENABLE", "1", TRUE); + g_setenv ("GS_SELF_TEST_PROVENANCE_SOURCES", "london*,boston", TRUE); + g_setenv ("GS_SELF_TEST_PROVENANCE_LICENSE_SOURCES", "london*,boston", TRUE); + g_setenv ("GS_SELF_TEST_PROVENANCE_LICENSE_URL", "https://www.debian.org/", TRUE); + g_setenv ("GNOME_SOFTWARE_POPULAR", "", TRUE); + + /* Use a common cache directory for all tests, since the appstream + * plugin uses it and cannot be reinitialised for each test. */ + tmp_root = g_dir_make_tmp ("gnome-software-dummy-test-XXXXXX", NULL); + g_assert (tmp_root != NULL); + g_setenv ("GS_SELF_TEST_CACHEDIR", tmp_root, TRUE); + + xml = g_strdup ("<?xml version=\"1.0\"?>\n" + "<components version=\"0.9\">\n" + " <component type=\"desktop\">\n" + " <id>chiron.desktop</id>\n" + " <name>Chiron</name>\n" + " <pkgname>chiron</pkgname>\n" + " </component>\n" + " <component type=\"desktop\">\n" + " <id>zeus.desktop</id>\n" + " <name>Zeus</name>\n" + " <summary>A teaching application</summary>\n" + " <pkgname>zeus</pkgname>\n" + " <icon type=\"stock\">drive-harddisk</icon>\n" + " <categories>\n" + " <category>AudioVideo</category>\n" + " <category>Player</category>\n" + " </categories>\n" + " <languages>\n" + " <lang percentage=\"100\">en_GB</lang>\n" + " </languages>\n" + " </component>\n" + " <component type=\"desktop\">\n" + " <id>mate-spell.desktop</id>\n" + " <name>Spell</name>\n" + " <summary>A spelling application for MATE</summary>\n" + " <pkgname>mate-spell</pkgname>\n" + " <icon type=\"stock\">drive-harddisk</icon>\n" + " <project_group>MATE</project_group>\n" + " </component>\n" + " <component type=\"addon\">\n" + " <id>zeus-spell.addon</id>\n" + " <extends>zeus.desktop</extends>\n" + " <name>Spell Check</name>\n" + " <summary>Check the spelling when teaching</summary>\n" + " <pkgname>zeus-spell</pkgname>\n" + " </component>\n" + " <component type=\"desktop\">\n" + " <id>Uninstall Zeus.desktop</id>\n" + " <name>Uninstall Zeus</name>\n" + " <summary>Uninstall the teaching application</summary>\n" + " <icon type=\"stock\">drive-harddisk</icon>\n" + " </component>\n" + " <component type=\"os-upgrade\">\n" + " <id>org.fedoraproject.release-rawhide.upgrade</id>\n" + " <name>Fedora Rawhide</name>\n" + " <summary>Release specific tagline</summary>\n" + " <pkgname>fedora-release</pkgname>\n" + " </component>\n" + " <info>\n" + " <scope>user</scope>\n" + " </info>\n" + "</components>\n"); + g_setenv ("GS_SELF_TEST_APPSTREAM_XML", xml, TRUE); + + /* only critical and error are fatal */ + g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); + + /* we can only load this once per process */ + plugin_loader = gs_plugin_loader_new (); + g_signal_connect (plugin_loader, "status-changed", + G_CALLBACK (gs_plugin_loader_status_changed_cb), NULL); + gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR); + gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR_CORE); + ret = gs_plugin_loader_setup (plugin_loader, + (gchar**) allowlist, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert (!gs_plugin_loader_get_enabled (plugin_loader, "notgoingtoexist")); + g_assert (gs_plugin_loader_get_enabled (plugin_loader, "appstream")); + g_assert (gs_plugin_loader_get_enabled (plugin_loader, "dummy")); + + /* plugin tests go here */ + g_test_add_data_func ("/gnome-software/plugins/dummy/wildcard", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_wildcard_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/plugin-cache", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_plugin_cache_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/key-colors", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_key_colors_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/search", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_search_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/search-alternate", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_search_alternate_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/hang", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_hang_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/search{invalid}", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_search_invalid_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/url-to-app", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_url_to_app_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/install", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_install_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/error", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_error_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/installed", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_installed_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/refine", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_refine_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/updates", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_updates_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/distro-upgrades", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_distro_upgrades_func); + g_test_add_data_func ("/gnome-software/plugins/dummy/metadata-quirks", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_metadata_quirks); + g_test_add_data_func ("/gnome-software/plugins/dummy/limit-parallel-ops", + plugin_loader, + (GTestDataFunc) gs_plugins_dummy_limit_parallel_ops_func); + retval = g_test_run (); + + /* Clean up. */ + gs_utils_rmtree (tmp_root, NULL); + + return retval; +} diff --git a/plugins/dummy/meson.build b/plugins/dummy/meson.build new file mode 100644 index 0000000..9235f4e --- /dev/null +++ b/plugins/dummy/meson.build @@ -0,0 +1,41 @@ +cargs = ['-DG_LOG_DOMAIN="GsPluginDummy"'] +cargs += ['-DLOCALPLUGINDIR="' + meson.current_build_dir() + '"'] +cargs += ['-DLOCALPLUGINDIR_CORE="' + meson.current_build_dir() + '/../core"'] + +shared_module( + 'gs_plugin_dummy', + sources : 'gs-plugin-dummy.c', + include_directories : [ + include_directories('../..'), + include_directories('../../lib'), + ], + install : true, + install_dir: plugin_dir, + c_args : cargs, + dependencies : [appstream_glib, gio_unix, goa, gtk, libsoup], + link_with : [ + libgnomesoftware + ] +) + +if get_option('tests') + e = executable( + 'gs-self-test-dummy', + compiled_schemas, + sources : [ + 'gs-self-test.c' + ], + include_directories : [ + include_directories('../..'), + include_directories('../../lib'), + ], + dependencies : [ + plugin_libs, + ], + link_with : [ + libgnomesoftware + ], + c_args : cargs, + ) + test('gs-self-test-dummy', e, suite: ['plugins', 'dummy'], env: test_env) +endif |