[gnome-software] Add several tests for installing, removing and updating flatpaks
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add several tests for installing, removing and updating flatpaks
- Date: Mon, 20 Feb 2017 16:54:10 +0000 (UTC)
commit 715e46aba21cfcdfacd0ee44cddba02a8264f677
Author: Richard Hughes <richard hughsie com>
Date: Sun Feb 19 09:59:17 2017 +0000
Add several tests for installing, removing and updating flatpaks
Also, fix several of the bugs found.
.../flatpak/app-missing-runtime/org.test.Chiron | 1 +
.../flatpak/app-update/org.test.Chiron/.gitignore | 1 +
.../app-update/org.test.Chiron/files/bin/chiron.sh | 2 +
.../icons/flatpak/128x128/org.test.Chiron.png | Bin 0 -> 373 bytes
.../icons/flatpak/64x64/org.test.Chiron.png | Bin 0 -> 168 bytes
.../share/app-info/xmls/org.test.Chiron.xml.gz | Bin 0 -> 434 bytes
.../share/appdata/org.test.Chiron.appdata.xml | 0
.../share/applications/org.test.Chiron.desktop | 1 +
.../icons/hicolor/128x128/apps/org.test.Chiron.png | 1 +
.../org.test.Chiron}/metadata | 0
.../app-with-runtime/org.test.Chiron/.gitignore | 2 +
.../org.test.Chiron}/files/bin/chiron.sh | 0
.../share/appdata/org.test.Chiron.appdata.xml | 3 -
.../share/applications/org.test.Chiron.desktop | 0
.../icons/hicolor/128x128/apps/org.test.Chiron.png | Bin 334 -> 334 bytes
.../org.test.Chiron}/metadata | 0
.../org.test.Runtime/files/.empty | 0
.../org.test.Runtime/files/.gitignore | 0
.../share/metainfo/org.test.Runtime.metainfo.xml | 0
.../org.test.Runtime/metadata | 0
.../org.test.Runtime/usr/share/libtest/README | 0
data/tests/flatpak/build-flatpak.sh | 13 -
data/tests/flatpak/build.py | 69 ++++
src/gs-plugin-loader.c | 29 ++
src/gs-plugin-loader.h | 3 +
src/gs-plugin.c | 2 +
src/gs-self-test.c | 356 +++++++++++++++++++-
src/plugins/gs-appstream.c | 4 +
src/plugins/gs-flatpak.c | 49 +++-
src/plugins/gs-plugin-appstream.c | 25 ++-
src/plugins/gs-plugin-flatpak.c | 3 +
31 files changed, 532 insertions(+), 32 deletions(-)
---
diff --git a/data/tests/flatpak/app-missing-runtime/org.test.Chiron
b/data/tests/flatpak/app-missing-runtime/org.test.Chiron
new file mode 120000
index 0000000..d9384e4
--- /dev/null
+++ b/data/tests/flatpak/app-missing-runtime/org.test.Chiron
@@ -0,0 +1 @@
+../app-with-runtime/org.test.Chiron/
\ No newline at end of file
diff --git a/data/tests/flatpak/app-update/org.test.Chiron/.gitignore
b/data/tests/flatpak/app-update/org.test.Chiron/.gitignore
new file mode 120000
index 0000000..7f06bb9
--- /dev/null
+++ b/data/tests/flatpak/app-update/org.test.Chiron/.gitignore
@@ -0,0 +1 @@
+../app-with-runtime/org.test.Chiron/.gitignore
\ No newline at end of file
diff --git a/data/tests/flatpak/app-update/org.test.Chiron/files/bin/chiron.sh
b/data/tests/flatpak/app-update/org.test.Chiron/files/bin/chiron.sh
new file mode 100644
index 0000000..dfed21c
--- /dev/null
+++ b/data/tests/flatpak/app-update/org.test.Chiron/files/bin/chiron.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Hello world, with upgrades"
diff --git
a/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/128x128/org.test.Chiron.png
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/128x128/org.test.Chiron.png
new file mode 100644
index 0000000..5a244e6
Binary files /dev/null and
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/128x128/org.test.Chiron.png
differ
diff --git
a/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/64x64/org.test.Chiron.png
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/64x64/org.test.Chiron.png
new file mode 100644
index 0000000..ed8d273
Binary files /dev/null and
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/icons/flatpak/64x64/org.test.Chiron.png
differ
diff --git a/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/xmls/org.test.Chiron.xml.gz
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/xmls/org.test.Chiron.xml.gz
new file mode 100644
index 0000000..e40f14b
Binary files /dev/null and
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/app-info/xmls/org.test.Chiron.xml.gz differ
diff --git a/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/appdata/org.test.Chiron.appdata.xml
similarity index 100%
copy from data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
copy to data/tests/flatpak/app-update/org.test.Chiron/files/share/appdata/org.test.Chiron.appdata.xml
diff --git a/data/tests/flatpak/app-update/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
new file mode 120000
index 0000000..2b06818
--- /dev/null
+++ b/data/tests/flatpak/app-update/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
@@ -0,0 +1 @@
+../../../../../app-missing-runtime/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
\ No newline at end of file
diff --git
a/data/tests/flatpak/app-update/org.test.Chiron/files/share/icons/hicolor/128x128/apps/org.test.Chiron.png
b/data/tests/flatpak/app-update/org.test.Chiron/files/share/icons/hicolor/128x128/apps/org.test.Chiron.png
new file mode 120000
index 0000000..9c37986
--- /dev/null
+++ b/data/tests/flatpak/app-update/org.test.Chiron/files/share/icons/hicolor/128x128/apps/org.test.Chiron.png
@@ -0,0 +1 @@
+../../../../../../../../app-missing-runtime/org.test.Chiron/files/share/icons/hicolor/128x128/apps/org.test.Chiron.png
\ No newline at end of file
diff --git a/data/tests/flatpak/chiron/metadata b/data/tests/flatpak/app-update/org.test.Chiron/metadata
similarity index 100%
copy from data/tests/flatpak/chiron/metadata
copy to data/tests/flatpak/app-update/org.test.Chiron/metadata
diff --git a/data/tests/flatpak/app-with-runtime/org.test.Chiron/.gitignore
b/data/tests/flatpak/app-with-runtime/org.test.Chiron/.gitignore
new file mode 100644
index 0000000..fea15c0
--- /dev/null
+++ b/data/tests/flatpak/app-with-runtime/org.test.Chiron/.gitignore
@@ -0,0 +1,2 @@
+export
+files/share/app-info
diff --git a/data/tests/flatpak/chiron/files/bin/chiron.sh
b/data/tests/flatpak/app-with-runtime/org.test.Chiron/files/bin/chiron.sh
similarity index 100%
rename from data/tests/flatpak/chiron/files/bin/chiron.sh
rename to data/tests/flatpak/app-with-runtime/org.test.Chiron/files/bin/chiron.sh
diff --git a/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
b/data/tests/flatpak/app-with-runtime/org.test.Chiron/files/share/appdata/org.test.Chiron.appdata.xml
similarity index 83%
rename from data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
rename to data/tests/flatpak/app-with-runtime/org.test.Chiron/files/share/appdata/org.test.Chiron.appdata.xml
index b6d5138..0d912a8 100644
--- a/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
+++ b/data/tests/flatpak/app-with-runtime/org.test.Chiron/files/share/appdata/org.test.Chiron.appdata.xml
@@ -9,9 +9,6 @@
<description><p>Long description.</p></description>
<url type="homepage">http://127.0.0.1/</url>
<releases>
- <release date="2015-02-13" version="1.2.4">
- <description><p>This is best.</p></description>
- </release>
<release date="2014-12-15" version="1.2.3">
<description><p>This is better.</p></description>
</release>
diff --git a/data/tests/flatpak/chiron/files/share/applications/org.test.Chiron.desktop
b/data/tests/flatpak/app-with-runtime/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
similarity index 100%
rename from data/tests/flatpak/chiron/files/share/applications/org.test.Chiron.desktop
rename to data/tests/flatpak/app-with-runtime/org.test.Chiron/files/share/applications/org.test.Chiron.desktop
diff --git a/data/tests/flatpak/chiron/metadata b/data/tests/flatpak/app-with-runtime/org.test.Chiron/metadata
similarity index 100%
rename from data/tests/flatpak/chiron/metadata
rename to data/tests/flatpak/app-with-runtime/org.test.Chiron/metadata
diff --git a/data/tests/flatpak/org.test.Runtime/files/.empty
b/data/tests/flatpak/app-with-runtime/org.test.Runtime/files/.empty
similarity index 100%
rename from data/tests/flatpak/org.test.Runtime/files/.empty
rename to data/tests/flatpak/app-with-runtime/org.test.Runtime/files/.empty
diff --git a/data/tests/flatpak/org.test.Runtime/files/.gitignore
b/data/tests/flatpak/app-with-runtime/org.test.Runtime/files/.gitignore
similarity index 100%
rename from data/tests/flatpak/org.test.Runtime/files/.gitignore
rename to data/tests/flatpak/app-with-runtime/org.test.Runtime/files/.gitignore
diff --git a/data/tests/flatpak/org.test.Runtime/files/share/metainfo/org.test.Runtime.metainfo.xml
b/data/tests/flatpak/app-with-runtime/org.test.Runtime/files/share/metainfo/org.test.Runtime.metainfo.xml
similarity index 100%
rename from data/tests/flatpak/org.test.Runtime/files/share/metainfo/org.test.Runtime.metainfo.xml
rename to
data/tests/flatpak/app-with-runtime/org.test.Runtime/files/share/metainfo/org.test.Runtime.metainfo.xml
diff --git a/data/tests/flatpak/org.test.Runtime/metadata
b/data/tests/flatpak/app-with-runtime/org.test.Runtime/metadata
similarity index 100%
rename from data/tests/flatpak/org.test.Runtime/metadata
rename to data/tests/flatpak/app-with-runtime/org.test.Runtime/metadata
diff --git a/data/tests/flatpak/org.test.Runtime/usr/share/libtest/README
b/data/tests/flatpak/app-with-runtime/org.test.Runtime/usr/share/libtest/README
similarity index 100%
rename from data/tests/flatpak/org.test.Runtime/usr/share/libtest/README
rename to data/tests/flatpak/app-with-runtime/org.test.Runtime/usr/share/libtest/README
diff --git a/data/tests/flatpak/build.py b/data/tests/flatpak/build.py
new file mode 100755
index 0000000..b29579e
--- /dev/null
+++ b/data/tests/flatpak/build.py
@@ -0,0 +1,69 @@
+#!/bin/python
+
+import subprocess
+import os
+import shutil
+
+def build_flatpak(appid, srcdir, repodir, cleanrepodir=True):
+ print 'Building %s from %s into %s' % (appid, srcdir, repodir)
+
+ # delete repodir
+ if cleanrepodir and os.path.exists(repodir):
+ print "Deleting %s" % repodir
+ #shutil.rmtree(repodir)
+
+ # delete exportdir
+ exportdir = os.path.join(srcdir, appid, 'export')
+ if os.path.exists(exportdir):
+ print "Deleting %s" % exportdir
+ shutil.rmtree(exportdir)
+
+ # finish the build
+ argv = ['flatpak', 'build-finish']
+ argv.append(os.path.join(srcdir, appid))
+ subprocess.call(argv)
+
+ # compose AppStream data
+ argv = ['appstream-compose']
+ argv.append('--origin=flatpak')
+ argv.append('--basename=%s' % appid)
+ argv.append('--prefix=%s' % os.path.join(srcdir, appid, 'files'))
+ argv.append('--output-dir=%s' % os.path.join(srcdir, appid, 'files/share/app-info/xmls'))
+ argv.append(appid)
+ subprocess.call(argv)
+
+ # export into repo
+ argv = ['flatpak', 'build-export']
+ argv.append(repodir)
+ argv.append(os.path.join(srcdir, appid))
+ argv.append('--update-appstream')
+ if appid.find('Runtime') != -1:
+ argv.append('--runtime')
+ subprocess.call(argv)
+
+# normal app with runtime in same remote
+build_flatpak('org.test.Chiron',
+ 'app-with-runtime',
+ 'app-with-runtime/repo')
+build_flatpak('org.test.Runtime',
+ 'app-with-runtime',
+ 'app-with-runtime/repo',
+ cleanrepodir=False)
+
+# app referencing remote that cannot be found
+build_flatpak('org.test.Chiron',
+ 'app-with-runtime',
+ 'app-missing-runtime/repo')
+
+# app with an update
+build_flatpak('org.test.Chiron',
+ 'app-with-runtime',
+ 'app-update/repo')
+build_flatpak('org.test.Runtime',
+ 'app-with-runtime',
+ 'app-update/repo',
+ cleanrepodir=False)
+build_flatpak('org.test.Chiron',
+ 'app-update',
+ 'app-update/repo',
+ cleanrepodir=False)
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 29f9c1c..1d1b9df 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -3494,6 +3494,35 @@ gs_plugin_loader_plugin_dir_changed_cb (GFileMonitor *monitor,
}
/**
+ * gs_plugin_loader_setup_again:
+ * @plugin_loader: a #GsPluginLoader
+ *
+ * Calls setup on each plugin. This should only be used from the self tests
+ * and in a controlled way.
+ */
+void
+gs_plugin_loader_setup_again (GsPluginLoader *plugin_loader)
+{
+ GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+ g_autoptr(GsPluginLoaderJob) job = gs_plugin_loader_job_new (plugin_loader);
+ job->action = GS_PLUGIN_ACTION_SETUP;
+ job->failure_flags = GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE;
+ job->function_name = "gs_plugin_setup";
+ for (guint i = 0; i < priv->plugins->len; i++) {
+ GsPlugin *plugin = g_ptr_array_index (priv->plugins, i);
+ g_autoptr(GError) error_local = NULL;
+ if (!gs_plugin_get_enabled (plugin))
+ continue;
+ if (!gs_plugin_loader_call_vfunc (job, plugin, NULL, NULL,
+ NULL, &error_local)) {
+ g_warning ("resetup of %s failed: %s",
+ gs_plugin_get_name (plugin),
+ error_local->message);
+ }
+ }
+}
+
+/**
* gs_plugin_loader_setup:
* @plugin_loader: a #GsPluginLoader
* @whitelist: list of plugin names, or %NULL
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 212cc65..279be97 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -277,6 +277,9 @@ AsProfile *gs_plugin_loader_get_profile (GsPluginLoader *plugin_loader);
GsApp *gs_plugin_loader_app_create (GsPluginLoader *plugin_loader,
const gchar *unique_id);
+/* only useful from the self tests */
+void gs_plugin_loader_setup_again (GsPluginLoader *plugin_loader);
+
G_END_DECLS
#endif /* __GS_PLUGIN_LOADER_H */
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index 4823a34..d858632 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -345,6 +345,8 @@ gs_plugin_get_symbol (GsPlugin *plugin, const gchar *function_name)
gpointer func = NULL;
g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&priv->vfuncs_mutex);
+ g_return_val_if_fail (function_name != NULL, NULL);
+
/* disabled plugins shouldn't be checked */
if (!priv->enabled)
return NULL;
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 824ca8e..da2ef7a 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -1092,7 +1092,7 @@ gs_plugin_loader_flatpak_repo_func (GsPluginLoader *plugin_loader)
}
static void
-gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
+gs_plugin_loader_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
{
GsApp *app;
GsApp *runtime;
@@ -1115,12 +1115,15 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
g_autoptr(GsAppList) list = NULL;
g_autoptr(GsAppList) sources = NULL;
+ /* drop all caches */
+ gs_plugin_loader_setup_again (plugin_loader);
+
/* no flatpak, abort */
if (!gs_plugin_loader_get_enabled (plugin_loader, "flatpak"))
return;
/* no files to use */
- repodir_fn = gs_test_get_filename ("tests/flatpak/repo");
+ repodir_fn = gs_test_get_filename ("tests/flatpak/app-with-runtime/repo");
if (repodir_fn == NULL ||
!g_file_test (repodir_fn, G_FILE_TEST_EXISTS)) {
g_test_skip ("no flatpak test repo");
@@ -1143,7 +1146,7 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
/* add a remote */
app_source = gs_app_new ("test");
- testdir = gs_test_get_filename ("tests/flatpak");
+ testdir = gs_test_get_filename ("tests/flatpak/app-with-runtime");
if (testdir == NULL)
return;
testdir_repourl = g_strdup_printf ("file://%s/repo", testdir);
@@ -1196,6 +1199,7 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
"Bingo",
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
NULL,
@@ -1215,10 +1219,9 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
GS_APP_KUDO_SANDBOXED_SECURE |
GS_APP_KUDO_SANDBOXED);
g_assert_cmpstr (gs_app_get_origin_hostname (app), ==, "");
- g_assert_cmpstr (gs_app_get_update_version (app), ==, "1.2.4");
- g_assert_cmpstr (gs_app_get_update_details (app), ==,
- "Version 1.2.4:\nThis is best.\n\n"
- "Version 1.2.3:\nThis is better.");
+ g_assert_cmpstr (gs_app_get_version (app), ==, "master");
+ g_assert_cmpstr (gs_app_get_update_version (app), ==, NULL);
+ g_assert_cmpstr (gs_app_get_update_details (app), ==, NULL);
g_assert_cmpint (gs_app_get_update_urgency (app), ==, AS_URGENCY_KIND_UNKNOWN);
/* install, also installing runtime */
@@ -1230,6 +1233,7 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED);
+ g_assert_cmpstr (gs_app_get_version (app), ==, "1.2.3");
/* check the application exists in the right places */
metadata_fn = g_build_filename (root,
@@ -1317,6 +1321,334 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
}
static void
+gs_plugin_loader_flatpak_app_missing_runtime_func (GsPluginLoader *plugin_loader)
+{
+ GsApp *app;
+ gboolean ret;
+ g_autofree gchar *repodir_fn = NULL;
+ g_autofree gchar *testdir = NULL;
+ g_autofree gchar *testdir_repourl = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GsApp) app_source = NULL;
+ g_autoptr(GsAppList) list = NULL;
+
+ /* drop all caches */
+ gs_plugin_loader_setup_again (plugin_loader);
+
+ /* no flatpak, abort */
+ if (!gs_plugin_loader_get_enabled (plugin_loader, "flatpak"))
+ return;
+
+ /* no files to use */
+ repodir_fn = gs_test_get_filename ("tests/flatpak/app-missing-runtime/repo");
+ if (repodir_fn == NULL ||
+ !g_file_test (repodir_fn, G_FILE_TEST_EXISTS)) {
+ g_test_skip ("no flatpak test repo");
+ return;
+ }
+
+ /* add a remote */
+ app_source = gs_app_new ("test");
+ testdir = gs_test_get_filename ("tests/flatpak/app-missing-runtime");
+ if (testdir == NULL)
+ return;
+ testdir_repourl = g_strdup_printf ("file://%s/repo", testdir);
+ gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+ gs_app_set_management_plugin (app_source, "flatpak");
+ gs_app_set_state (app_source, AS_APP_STATE_AVAILABLE);
+ gs_app_set_metadata (app_source, "flatpak::url", testdir_repourl);
+ ret = gs_plugin_loader_app_action (plugin_loader, app_source,
+ GS_PLUGIN_ACTION_INSTALL,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpint (gs_app_get_state (app_source), ==, AS_APP_STATE_INSTALLED);
+
+ /* refresh the appstream metadata */
+ ret = gs_plugin_loader_refresh (plugin_loader,
+ G_MAXUINT,
+ GS_PLUGIN_REFRESH_FLAGS_METADATA,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* find available application */
+ list = gs_plugin_loader_search (plugin_loader,
+ "Bingo",
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (list != NULL);
+
+ /* make sure there is one entry, the flatpak 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), ==, "org.test.Chiron.desktop");
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+
+ /* install, also installing runtime */
+ ret = gs_plugin_loader_app_action (plugin_loader, app,
+ GS_PLUGIN_ACTION_INSTALL,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY |
+ GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE,
+ NULL,
+ &error);
+ g_assert_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED);
+ g_assert (!ret);
+ g_clear_error (&error);
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+
+ /* remove the remote */
+ ret = gs_plugin_loader_app_action (plugin_loader, app_source,
+ GS_PLUGIN_ACTION_REMOVE,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpint (gs_app_get_state (app_source), ==, AS_APP_STATE_AVAILABLE);
+}
+
+static void
+update_app_progress_notify_cb (GsApp *app, GParamSpec *pspec, gpointer user_data)
+{
+ g_debug ("progress now %u%%", gs_app_get_progress (app));
+ if (user_data != NULL) {
+ guint *tmp = (guint *) user_data;
+ (*tmp)++;
+ }
+}
+
+static void
+update_app_state_notify_cb (GsApp *app, GParamSpec *pspec, gpointer user_data)
+{
+ AsAppState state = gs_app_get_state (app);
+ g_debug ("state now %s", as_app_state_to_string (state));
+ if (state == AS_APP_STATE_INSTALLING) {
+ gboolean *tmp = (gboolean *) user_data;
+ *tmp = TRUE;
+ }
+}
+
+static void
+update_app_action_finish_sync (GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+ GMainLoop *loop = (GMainLoop *) user_data;
+ gboolean ret;
+ g_autoptr(GError) error = NULL;
+ ret = gs_plugin_loader_app_action_finish (plugin_loader, res, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_main_loop_quit (loop);
+}
+
+static void
+gs_plugin_loader_flatpak_app_update_func (GsPluginLoader *plugin_loader)
+{
+ GsApp *app;
+ GsApp *app_tmp;
+ GsApp *runtime;
+ gboolean got_progress_installing = FALSE;
+ gboolean ret;
+ guint notify_progress_id;
+ guint notify_state_id;
+ guint progress_cnt = 0;
+ g_autofree gchar *repodir1_fn = NULL;
+ g_autofree gchar *repodir2_fn = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GsApp) app_source = NULL;
+ g_autoptr(GsAppList) list = NULL;
+ g_autoptr(GsAppList) list_updates = NULL;
+ g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE);
+
+ /* drop all caches */
+ gs_plugin_loader_setup_again (plugin_loader);
+
+ /* no flatpak, abort */
+ if (!gs_plugin_loader_get_enabled (plugin_loader, "flatpak"))
+ return;
+
+ /* no files to use */
+ repodir1_fn = gs_test_get_filename ("tests/flatpak/app-with-runtime/repo");
+ if (repodir1_fn == NULL ||
+ !g_file_test (repodir1_fn, G_FILE_TEST_EXISTS)) {
+ g_test_skip ("no flatpak test repo");
+ return;
+ }
+ repodir2_fn = gs_test_get_filename ("tests/flatpak/app-update/repo");
+ if (repodir2_fn == NULL ||
+ !g_file_test (repodir2_fn, G_FILE_TEST_EXISTS)) {
+ g_test_skip ("no flatpak test repo");
+ return;
+ }
+
+ /* add indirection so we can switch this after install */
+ g_assert (symlink (repodir1_fn, "/var/tmp/self-test/repo") == 0);
+
+ /* add a remote */
+ app_source = gs_app_new ("test");
+ gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+ gs_app_set_management_plugin (app_source, "flatpak");
+ gs_app_set_state (app_source, AS_APP_STATE_AVAILABLE);
+ gs_app_set_metadata (app_source, "flatpak::url", "file:///var/tmp/self-test/repo");
+ ret = gs_plugin_loader_app_action (plugin_loader, app_source,
+ GS_PLUGIN_ACTION_INSTALL,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpint (gs_app_get_state (app_source), ==, AS_APP_STATE_INSTALLED);
+
+ /* refresh the appstream metadata */
+ ret = gs_plugin_loader_refresh (plugin_loader,
+ G_MAXUINT,
+ GS_PLUGIN_REFRESH_FLAGS_METADATA,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* find available application */
+ list = gs_plugin_loader_search (plugin_loader,
+ "Bingo",
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (list != NULL);
+
+ /* make sure there is one entry, the flatpak 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), ==, "org.test.Chiron.desktop");
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+
+ /* install, also installing runtime */
+ ret = gs_plugin_loader_app_action (plugin_loader, app,
+ GS_PLUGIN_ACTION_INSTALL,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY |
+ GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED);
+ g_assert_cmpstr (gs_app_get_version (app), ==, "1.2.3");
+ g_assert_cmpstr (gs_app_get_update_version (app), ==, NULL);
+ g_assert_cmpstr (gs_app_get_update_details (app), ==, NULL);
+
+ /* switch to the new repo */
+ g_assert (unlink ("/var/tmp/self-test/repo") == 0);
+ g_assert (symlink (repodir2_fn, "/var/tmp/self-test/repo") == 0);
+
+ /* refresh the appstream metadata */
+ ret = gs_plugin_loader_refresh (plugin_loader,
+ 0, /* force now */
+ GS_PLUGIN_REFRESH_FLAGS_METADATA |
+ GS_PLUGIN_REFRESH_FLAGS_PAYLOAD,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* get the updates list */
+ list_updates = gs_plugin_loader_get_updates (plugin_loader,
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_UPDATE_DETAILS,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (list_updates != NULL);
+
+ /* make sure there are two entries */
+ g_assert_cmpint (gs_app_list_length (list_updates), >, 3);
+ for (guint i = 0; i < gs_app_list_length (list_updates); i++) {
+ app_tmp = gs_app_list_index (list_updates, i);
+ g_debug ("got update %s", gs_app_get_unique_id (app_tmp));
+ }
+
+ /* check they are the same GObject */
+ app_tmp = gs_app_list_lookup (list_updates, "*/flatpak/test/*/org.test.Chiron.desktop/*");
+ g_assert (app_tmp == app);
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_UPDATABLE_LIVE);
+ g_assert_cmpstr (gs_app_get_update_details (app), ==, "Version 1.2.4:\nThis is best.\n\nVersion
1.2.3:\nThis is better.");
+ g_assert_cmpstr (gs_app_get_update_version (app), ==, "1.2.4");
+
+ /* care about signals */
+ notify_state_id =
+ g_signal_connect (app, "notify::state",
+ G_CALLBACK (update_app_state_notify_cb),
+ &got_progress_installing);
+ notify_progress_id =
+ g_signal_connect (app, "notify::progress",
+ G_CALLBACK (update_app_progress_notify_cb),
+ &progress_cnt);
+
+ /* use a mainloop so we get the events in the default context */
+ gs_plugin_loader_app_action_async (plugin_loader, app,
+ GS_PLUGIN_ACTION_UPDATE,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY |
+ GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE,
+ NULL,
+ update_app_action_finish_sync,
+ loop);
+ g_main_loop_run (loop);
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED);
+ g_assert_cmpstr (gs_app_get_version (app), ==, "1.2.4");
+ g_assert_cmpstr (gs_app_get_update_version (app), ==, NULL);
+ g_assert_cmpstr (gs_app_get_update_details (app), ==, NULL);
+ g_assert (got_progress_installing);
+ //g_assert_cmpint (progress_cnt, >, 20); //FIXME: bug in OSTree
+
+ /* no longer care */
+ g_signal_handler_disconnect (app, notify_state_id);
+ g_signal_handler_disconnect (app, notify_progress_id);
+
+ /* remove the app */
+ ret = gs_plugin_loader_app_action (plugin_loader, app,
+ GS_PLUGIN_ACTION_REMOVE,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* remove the runtime */
+ runtime = gs_app_get_runtime (app);
+ g_assert (runtime != NULL);
+ g_assert_cmpstr (gs_app_get_unique_id (runtime), ==,
"user/flatpak/test/runtime/org.test.Runtime.runtime/master");
+ ret = gs_plugin_loader_app_action (plugin_loader, runtime,
+ GS_PLUGIN_ACTION_REMOVE,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* remove the remote */
+ ret = gs_plugin_loader_app_action (plugin_loader, app_source,
+ GS_PLUGIN_ACTION_REMOVE,
+ GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpint (gs_app_get_state (app_source), ==, AS_APP_STATE_AVAILABLE);
+}
+
+static void
gs_plugin_loader_plugin_cache_func (GsPluginLoader *plugin_loader)
{
GsApp *app1;
@@ -1656,9 +1988,15 @@ main (int argc, char **argv)
g_test_add_data_func ("/gnome-software/plugin-loader{repos}",
plugin_loader,
(GTestDataFunc) gs_plugin_loader_repos_func);
- g_test_add_data_func ("/gnome-software/plugin-loader{flatpak}",
+ g_test_add_data_func ("/gnome-software/plugin-loader{flatpak-app-with-runtime}",
+ plugin_loader,
+ (GTestDataFunc) gs_plugin_loader_flatpak_app_with_runtime_func);
+ g_test_add_data_func ("/gnome-software/plugin-loader{flatpak-app-missing-runtime}",
+ plugin_loader,
+ (GTestDataFunc) gs_plugin_loader_flatpak_app_missing_runtime_func);
+ g_test_add_data_func ("/gnome-software/plugin-loader{flatpak-app-update-runtime}",
plugin_loader,
- (GTestDataFunc) gs_plugin_loader_flatpak_func);
+ (GTestDataFunc) gs_plugin_loader_flatpak_app_update_func);
g_test_add_data_func ("/gnome-software/plugin-loader{fwupd}",
plugin_loader,
(GTestDataFunc) gs_plugin_loader_fwupd_func);
diff --git a/src/plugins/gs-appstream.c b/src/plugins/gs-appstream.c
index 43a50ea..40be14a 100644
--- a/src/plugins/gs-appstream.c
+++ b/src/plugins/gs-appstream.c
@@ -392,6 +392,10 @@ gs_appstream_refine_app_updates (GsPlugin *plugin,
GPtrArray *releases;
g_autoptr(GPtrArray) updates_list = NULL;
+ /* only for UPDATABLE apps */
+ if (!gs_app_is_updatable (app))
+ return TRUE;
+
/* make a list of valid updates */
updates_list = g_ptr_array_new ();
releases = as_app_get_releases (item);
diff --git a/src/plugins/gs-flatpak.c b/src/plugins/gs-flatpak.c
index 227c841..ef2aca8 100644
--- a/src/plugins/gs-flatpak.c
+++ b/src/plugins/gs-flatpak.c
@@ -43,6 +43,7 @@ struct _GsFlatpak {
AsAppScope scope;
GsPlugin *plugin;
AsStore *store;
+ guint changed_id;
};
G_DEFINE_TYPE (GsFlatpak, gs_flatpak, G_TYPE_OBJECT)
@@ -440,8 +441,9 @@ gs_flatpak_setup (GsFlatpak *self, GCancellable *cancellable, GError **error)
gs_plugin_flatpak_error_convert (error);
return FALSE;
}
- g_signal_connect (self->monitor, "changed",
- G_CALLBACK (gs_plugin_flatpak_changed_cb), self);
+ self->changed_id =
+ g_signal_connect (self->monitor, "changed",
+ G_CALLBACK (gs_plugin_flatpak_changed_cb), self);
/* ensure the legacy AppStream symlink cache is deleted */
if (!gs_flatpak_symlinks_cleanup (self->installation, cancellable, error))
@@ -1029,6 +1031,9 @@ gs_flatpak_add_updates (GsFlatpak *self, GsAppList *list,
continue;
}
gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE);
+ gs_app_set_update_details (app, NULL);
+ gs_app_set_update_version (app, NULL);
+ gs_app_set_update_urgency (app, AS_URGENCY_KIND_UNKNOWN);
gs_app_set_size_download (app, 0);
gs_app_list_add (list_tmp, app);
}
@@ -1918,6 +1923,19 @@ gs_plugin_refine_item_size (GsFlatpak *self,
return TRUE;
}
+static void
+gs_flatpak_refine_appstream_release (AsApp *item, GsApp *app)
+{
+ AsRelease *rel = as_app_get_release_default (item);
+ if (!gs_app_is_installed (app))
+ return;
+ if (rel == NULL)
+ return;
+ if (as_release_get_version (rel) == NULL)
+ return;
+ gs_app_set_version (app, as_release_get_version (rel));
+}
+
static gboolean
gs_flatpak_refine_appstream (GsFlatpak *self, GsApp *app, GError **error)
{
@@ -1938,7 +1956,13 @@ gs_flatpak_refine_appstream (GsFlatpak *self, GsApp *app, GError **error)
AS_STORE_SEARCH_FLAG_USE_WILDCARDS);
if (item == NULL)
return TRUE;
- return gs_appstream_refine_app (self->plugin, app, item, error);
+ if (!gs_appstream_refine_app (self->plugin, app, item, error))
+ return FALSE;
+
+ /* use the default release as the version number */
+ gs_flatpak_refine_appstream_release (item, app);
+
+ return TRUE;
}
gboolean
@@ -2271,6 +2295,7 @@ install_runtime_for_app (GsFlatpak *self,
gs_flatpak_progress_cb, app,
cancellable, error);
if (xref == NULL) {
+ gs_plugin_flatpak_error_convert (error);
gs_app_set_state_recover (runtime);
gs_app_set_state_recover (app);
return FALSE;
@@ -2358,6 +2383,11 @@ gs_flatpak_app_install (GsFlatpak *self,
/* state is known */
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+
+ /* set new version */
+ if (!gs_flatpak_refine_appstream (self, app, error))
+ return FALSE;
+
return TRUE;
}
@@ -2396,6 +2426,14 @@ gs_flatpak_update_app (GsFlatpak *self,
/* state is known */
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+ gs_app_set_update_version (app, NULL);
+ gs_app_set_update_details (app, NULL);
+ gs_app_set_update_urgency (app, AS_URGENCY_KIND_UNKNOWN);
+
+ /* set new version */
+ if (!gs_flatpak_refine_appstream (self, app, error))
+ return FALSE;
+
return TRUE;
}
@@ -2929,6 +2967,11 @@ gs_flatpak_finalize (GObject *object)
g_return_if_fail (GS_IS_FLATPAK (object));
self = GS_FLATPAK (object);
+ if (self->changed_id > 0) {
+ g_signal_handler_disconnect (self->monitor, self->changed_id);
+ self->changed_id = 0;
+ }
+
g_object_unref (self->plugin);
g_object_unref (self->store);
g_hash_table_unref (self->broken_remotes);
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 7b54cb9..bb5bee4 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -39,6 +39,7 @@
struct GsPluginData {
AsStore *store;
GHashTable *app_hash_old;
+ guint store_changed_id;
};
#define GS_PLUGIN_NUMBER_CHANGED_RELOAD 10
@@ -186,7 +187,10 @@ void
gs_plugin_destroy (GsPlugin *plugin)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
- g_hash_table_unref (priv->app_hash_old);
+ if (priv->store_changed_id != 0)
+ g_signal_handler_disconnect (priv->store, priv->store_changed_id);
+ if (priv->app_hash_old != NULL)
+ g_hash_table_unref (priv->app_hash_old);
g_object_unref (priv->store);
}
@@ -250,6 +254,18 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
guint i;
g_autoptr(GHashTable) origins = NULL;
+ /* setup_again from the tests */
+ as_store_remove_all (priv->store);
+ if (priv->app_hash_old != NULL) {
+ if (priv->app_hash_old != NULL)
+ g_hash_table_unref (priv->app_hash_old);
+ priv->app_hash_old = NULL;
+ }
+ if (priv->store_changed_id != 0) {
+ g_signal_handler_disconnect (priv->store, priv->store_changed_id);
+ priv->store_changed_id = 0;
+ }
+
/* Parse the XML */
if (g_getenv ("GNOME_SOFTWARE_PREFER_LOCAL") != NULL) {
as_store_set_add_flags (priv->store,
@@ -293,9 +309,10 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
priv->app_hash_old = gs_plugin_appstream_create_app_hash (priv->store);
/* watch for changes */
- g_signal_connect (priv->store, "changed",
- G_CALLBACK (gs_plugin_appstream_store_changed_cb),
- plugin);
+ priv->store_changed_id =
+ g_signal_connect (priv->store, "changed",
+ G_CALLBACK (gs_plugin_appstream_store_changed_cb),
+ plugin);
/* ensure the token cache */
as_store_load_search_cache (priv->store);
diff --git a/src/plugins/gs-plugin-flatpak.c b/src/plugins/gs-plugin-flatpak.c
index b6220a7..4da4320 100644
--- a/src/plugins/gs-plugin-flatpak.c
+++ b/src/plugins/gs-plugin-flatpak.c
@@ -131,6 +131,9 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
+ /* clear in case we're called from resetup in the self tests */
+ g_ptr_array_set_size (priv->flatpaks, 0);
+
/* we use a permissions helper to elevate privs */
if (priv->has_system_helper && priv->destdir_for_tests == NULL) {
g_autoptr(FlatpakInstallation) installation = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]