[gnome-software/wip/hughsie/flatpak: 3/3] Add support for flatpak self tests



commit 6282c6afad30e627ce6b954dbbbb764845af7761
Author: Richard Hughes <richard hughsie com>
Date:   Wed May 11 17:23:02 2016 +0100

    Add support for flatpak self tests

 data/tests/flatpak/.gitignore                      |    2 +
 data/tests/flatpak/build-flatpak.sh                |    4 +
 data/tests/flatpak/chiron/files/bin/chiron.sh      |    2 +
 .../share/appdata/org.test.Chiron.appdata.xml      |   11 +
 .../share/applications/org.test.Chiron.desktop     |    6 +
 .../flatpak/chiron/files/share/icons/chiron.png    |  Bin 0 -> 334 bytes
 data/tests/flatpak/chiron/metadata                 |    4 +
 src/gs-self-test.c                                 |  232 ++++++++++++++++++++
 src/plugins/gs-plugin-flatpak.c                    |   15 ++-
 9 files changed, 275 insertions(+), 1 deletions(-)
---
diff --git a/data/tests/flatpak/.gitignore b/data/tests/flatpak/.gitignore
new file mode 100644
index 0000000..5e70496
--- /dev/null
+++ b/data/tests/flatpak/.gitignore
@@ -0,0 +1,2 @@
+chiron/files/share/app-info
+repo
diff --git a/data/tests/flatpak/build-flatpak.sh b/data/tests/flatpak/build-flatpak.sh
new file mode 100755
index 0000000..9083779
--- /dev/null
+++ b/data/tests/flatpak/build-flatpak.sh
@@ -0,0 +1,4 @@
+rm -rf repo
+flatpak build-export repo chiron
+appstream-compose --origin=flatpak --basename=org.test.Chiron --prefix=chiron/files 
--output-dir=chiron/files/share/app-info/xmls org.test.Chiron
+flatpak build-export repo chiron --update-appstream
diff --git a/data/tests/flatpak/chiron/files/bin/chiron.sh b/data/tests/flatpak/chiron/files/bin/chiron.sh
new file mode 100644
index 0000000..e61d501
--- /dev/null
+++ b/data/tests/flatpak/chiron/files/bin/chiron.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Hello world"
diff --git a/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml 
b/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
new file mode 100644
index 0000000..69d96d7
--- /dev/null
+++ b/data/tests/flatpak/chiron/files/share/appdata/org.test.Chiron.appdata.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2016 Richard Hughes <richard hughsie com> -->
+<component type="desktop">
+  <id>org.test.Chiron.desktop</id>
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>GPL-2.0+</project_license>
+  <name>Chiron</name>
+  <summary>Single line synopsis</summary>
+  <description><p>Long description.</p></description>
+  <url type="homepage">http://127.0.0.1/</url>
+</component>
diff --git a/data/tests/flatpak/chiron/files/share/applications/org.test.Chiron.desktop 
b/data/tests/flatpak/chiron/files/share/applications/org.test.Chiron.desktop
new file mode 100644
index 0000000..5e54081
--- /dev/null
+++ b/data/tests/flatpak/chiron/files/share/applications/org.test.Chiron.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Application
+Name=Chiron
+Exec=chiron.sh
+Icon=chiron
+Keywords=Bingo;
diff --git a/data/tests/flatpak/chiron/files/share/icons/chiron.png 
b/data/tests/flatpak/chiron/files/share/icons/chiron.png
new file mode 100644
index 0000000..0c38f2f
Binary files /dev/null and b/data/tests/flatpak/chiron/files/share/icons/chiron.png differ
diff --git a/data/tests/flatpak/chiron/metadata b/data/tests/flatpak/chiron/metadata
new file mode 100644
index 0000000..3c17007
--- /dev/null
+++ b/data/tests/flatpak/chiron/metadata
@@ -0,0 +1,4 @@
+[Application]
+name=org.test.Chiron
+runtime=org.gnome.Platform/x86_64/3.20
+command=chiron.sh
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index f641b11..25bd1ff 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -22,7 +22,9 @@
 #include "config.h"
 
 #include <glib-object.h>
+#include <glib/gstdio.h>
 #include <stdlib.h>
+#include <fnmatch.h>
 
 #include "gs-app-private.h"
 #include "gs-plugin.h"
@@ -46,6 +48,93 @@ gs_test_get_filename (const gchar *filename)
        return g_strdup (full_tmp);
 }
 
+/**
+ * gs_test_compare_lines:
+ **/
+static gboolean
+gs_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
+{
+       g_autofree gchar *output = NULL;
+
+       /* exactly the same */
+       if (g_strcmp0 (txt1, txt2) == 0)
+               return TRUE;
+
+       /* matches a pattern */
+       if (fnmatch (txt2, txt1, FNM_NOESCAPE) == 0)
+               return TRUE;
+
+       /* save temp files and diff them */
+       if (!g_file_set_contents ("/tmp/a", txt1, -1, error))
+               return FALSE;
+       if (!g_file_set_contents ("/tmp/b", txt2, -1, error))
+               return FALSE;
+       if (!g_spawn_command_line_sync ("diff -urNp /tmp/b /tmp/a",
+                                       &output, NULL, NULL, error))
+               return FALSE;
+
+       /* just output the diff */
+       g_set_error_literal (error, 1, 0, output);
+       return FALSE;
+}
+
+/**
+ * gs_test_check_contents:
+ **/
+static void
+gs_test_check_contents (const gchar *filename, const gchar *txt)
+{
+       g_autofree gchar *data = NULL;
+       g_autoptr(GError) error = NULL;
+       g_file_get_contents (filename, &data, NULL, &error);
+       g_assert_no_error (error);
+       gs_test_compare_lines (data, txt, &error);
+       g_assert_no_error (error);
+}
+
+/**
+ * gs_test_rmtree:
+ **/
+static gboolean
+gs_test_rmtree (const gchar *directory, GError **error)
+{
+       const gchar *filename;
+       g_autoptr(GDir) dir = NULL;
+
+       /* try to open */
+       dir = g_dir_open (directory, 0, error);
+       if (dir == NULL)
+               return FALSE;
+
+       /* find each */
+       while ((filename = g_dir_read_name (dir))) {
+               g_autofree gchar *src = NULL;
+               src = g_build_filename (directory, filename, NULL);
+               if (g_file_test (src, G_FILE_TEST_IS_DIR)) {
+                       if (!gs_test_rmtree (src, error))
+                               return FALSE;
+               } else {
+                       g_debug ("deleting %s", src);
+                       if (g_unlink (src) != 0) {
+                               g_set_error (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_FAILED,
+                                            "Failed to delete: %s", src);
+                               return FALSE;
+                       }
+               }
+       }
+       g_debug ("removing empty %s", directory);
+       if (g_rmdir (directory) != 0) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Failed to remove: %s", directory);
+               return FALSE;
+       }
+       return TRUE;
+}
+
 static gboolean
 gs_app_list_filter_cb (GsApp *app, gpointer user_data)
 {
@@ -563,9 +652,139 @@ gs_plugin_loader_fwupd_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (gs_app_get_id (app), ==, NULL);
 }
 
+static void
+gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
+{
+       const gchar *root;
+       gboolean ret;
+       GsApp *app;
+       g_autofree gchar *changed_fn = NULL;
+       g_autofree gchar *config_fn = NULL;
+       g_autofree gchar *testdir = NULL;
+       g_autoptr(GsAppList) list = NULL;
+       g_autoptr(GsAppList) sources = NULL;
+       g_autoptr(GError) error = NULL;
+       g_auto(GStrv) envp = NULL;
+       g_auto(GStrv) argv = NULL;
+
+       /* no flatpak, abort */
+       if (!gs_plugin_loader_get_enabled (plugin_loader, "flatpak"))
+               return;
+
+       /* check changed file exists */
+       root = g_getenv ("GS_SELF_TEST_FLATPACK_DATADIR");
+       changed_fn = g_build_filename (root, "flatpak", ".changed", NULL);
+       g_assert (g_file_test (changed_fn, G_FILE_TEST_IS_REGULAR));
+
+       /* check repo is set up */
+       config_fn = g_build_filename (root, "flatpak", "repo", "config", NULL);
+       gs_test_check_contents (config_fn,
+                               "[core]\n"
+                               "repo_version=1\n"
+                               "mode=bare-user\n");
+
+       /* set up fake environment */
+       envp = g_new0 (gchar *, 2);
+       envp[0] = g_strdup_printf ("XDG_DATA_HOME=%s", root);
+
+       /* add a remote */
+       //FIXME, use the plugin API
+       testdir = gs_test_get_filename ("tests/flatpak");
+       g_assert (testdir != NULL);
+       argv = g_new0 (gchar *, 7);
+       argv[0] = g_strdup ("/usr/bin/flatpak");
+       argv[1] = g_strdup ("--user");
+       argv[2] = g_strdup ("--no-gpg-verify");
+       argv[3] = g_strdup ("remote-add");
+       argv[4] = g_strdup ("test");
+       argv[5] = g_build_filename (testdir, "repo", NULL);
+       ret = g_spawn_sync (NULL, argv, envp, G_SPAWN_DEFAULT, NULL, NULL,
+                           NULL, NULL, NULL, &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+
+       /* check remote was set up */
+       gs_test_check_contents (config_fn,
+                               "[core]\n"
+                               "repo_version=1\n"
+                               "mode=bare-user\n"
+                               "\n"
+                               "[remote \"test\"]\n"
+                               
"url=file:///home/hughsie/Code/gnome3/gnome-software/data/tests/flatpak/repo\n"
+                               "gpg-verify=false\n"
+                               "gpg-verify-summary=false\n"
+                               );
+
+       //XDG_DATA_HOME=/tmp/flatpack/ flatpak remote-add --user --no-gpg-verify test 
../data/tests/flatpak/repo/
+
+       /* check the source now exists */
+       //FIXME
+       sources = gs_plugin_loader_get_sources (plugin_loader,
+                                               GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+                                               NULL,
+                                               &error);
+       g_assert_no_error (error);
+       g_assert (sources != NULL);
+       g_assert_cmpint (g_list_length (sources), ==, 1);
+       app = GS_APP (list->data);
+       g_assert_cmpstr (gs_app_get_id (app), ==, "test");
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_UNKNOWN);
+
+       /* refresh the appstream metadata */
+       //FIXME
+       //flatpak update --appstream gnome
+       ret = gs_plugin_loader_refresh (plugin_loader,
+                                       G_MAXUINT,
+                                       GS_PLUGIN_REFRESH_FLAGS_METADATA,
+                                       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_DEFAULT,
+                                       NULL,
+                                       &error);
+       g_assert_no_error (error);
+       g_assert (list != NULL);
+
+       //XDG_DATA_HOME=/tmp/flatpack/ flatpak --user remote-ls test
+
+       /* make sure there is one entry, the flatpak app */
+       g_assert_cmpint (g_list_length (list), ==, 1);
+       app = GS_APP (list->data);
+       g_assert_cmpstr (gs_app_get_id (app), ==, "org.gnome.Hello.desktop");
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+
+       /* install */
+       ret = gs_plugin_loader_app_action (plugin_loader, app,
+                                          GS_PLUGIN_LOADER_ACTION_INSTALL,
+                                          NULL,
+                                          &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+       g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED);
+
+       /* check the application exists in the right places */
+       //FIXME
+
+       /* remove the application */
+       ret = gs_plugin_loader_app_action (plugin_loader, app,
+                                          GS_PLUGIN_LOADER_ACTION_REMOVE,
+                                          NULL,
+                                          &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+       g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+}
+
 int
 main (int argc, char **argv)
 {
+       const gchar *tmp_root = "/tmp/self-test";
        gboolean ret;
        g_autofree gchar *fn = NULL;
        g_autofree gchar *xml = NULL;
@@ -576,6 +795,7 @@ main (int argc, char **argv)
                "dpkg",
                "dummy",
                "epiphany",
+               "flatpak",
                "fwupd",
                "hardcoded-blacklist",
                "icons",
@@ -596,6 +816,15 @@ main (int argc, char **argv)
        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 ("GS_SELF_TEST_FLATPACK_DATADIR", tmp_root, TRUE);
+
+       /* ensure test root does not exist */
+       if (g_file_test (tmp_root, G_FILE_TEST_EXISTS)) {
+               ret = gs_test_rmtree (tmp_root, &error);
+               g_assert_no_error (error);
+               g_assert (ret);
+       }
+       g_assert (!g_file_test (tmp_root, G_FILE_TEST_EXISTS));
 
        fn = gs_test_get_filename ("icons/hicolor/48x48/org.gnome.Software.png");
        g_assert (fn != NULL);
@@ -670,6 +899,9 @@ main (int argc, char **argv)
        g_assert (gs_plugin_loader_get_enabled (plugin_loader, "dummy"));
 
        /* plugin tests go here */
+       g_test_add_data_func ("/gnome-software/plugin-loader{flatpak}",
+                             plugin_loader,
+                             (GTestDataFunc) gs_plugin_loader_flatpak_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-plugin-flatpak.c b/src/plugins/gs-plugin-flatpak.c
index 7e2c8f0..486e27b 100644
--- a/src/plugins/gs-plugin-flatpak.c
+++ b/src/plugins/gs-plugin-flatpak.c
@@ -270,12 +270,25 @@ gboolean
 gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
+       const gchar *destdir;
        g_autoptr(AsProfileTask) ptask = NULL;
 
        /* we use a permissions helper to elevate privs */
        ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
                                          "flatpak::ensure-origin");
-       priv->installation = flatpak_installation_new_system (cancellable, error);
+       destdir = g_getenv ("GS_SELF_TEST_FLATPACK_DATADIR");
+       if (destdir != NULL) {
+               g_autofree gchar *full_path = g_build_filename (destdir,
+                                                               "flatpak",
+                                                               NULL);
+               g_autoptr(GFile) file = g_file_new_for_path (full_path);
+               priv->installation = flatpak_installation_new_for_path (file,
+                                                                       TRUE,
+                                                                       cancellable,
+                                                                       error);
+       } else {
+               priv->installation = flatpak_installation_new_system (cancellable, error);
+       }
        if (priv->installation == NULL)
                return FALSE;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]