diff options
author | Alexander Larsson <alexl@redhat.com> | 2019-09-27 16:39:58 +0200 |
---|---|---|
committer | Alexander Larsson <alexander.larsson@gmail.com> | 2019-10-02 14:57:11 +0200 |
commit | c15c1946ff7f8143e32519e1eb8014edf9d7dbfa (patch) | |
tree | 59528641da0ecea214ec72e8100aedab5e7145d6 | |
parent | 82328bee85165aba4deb6ef118e74733aec5f1a5 (diff) | |
download | flatpak-c15c1946ff7f8143e32519e1eb8014edf9d7dbfa.tar.gz |
test: Add test for update-portal monitoring
We add socat to the test runtime, and then we use that to run a
test app outside the sandbox as if it was inside.
The testcase connects creates a monitor and ensure we properly get signals
for updates.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | portal/org.freedesktop.portal.Flatpak.service.in | 2 | ||||
-rw-r--r-- | tests/Makefile-test-matrix.am.inc | 1 | ||||
-rw-r--r-- | tests/Makefile.am.inc | 19 | ||||
-rw-r--r-- | tests/libtest.sh | 8 | ||||
-rwxr-xr-x | tests/make-test-runtime.sh | 2 | ||||
-rw-r--r-- | tests/test-update-portal.c | 198 | ||||
-rwxr-xr-x | tests/test-update-portal.sh | 69 |
8 files changed, 295 insertions, 5 deletions
@@ -58,6 +58,7 @@ common/flatpak-enum-types.c common/flatpak-enum-types.h test-libflatpak httpcache +test-update-portal revokefs-fuse revokefs-demo Flatpak-1.0.* diff --git a/portal/org.freedesktop.portal.Flatpak.service.in b/portal/org.freedesktop.portal.Flatpak.service.in index 280e9b05..794d9343 100644 --- a/portal/org.freedesktop.portal.Flatpak.service.in +++ b/portal/org.freedesktop.portal.Flatpak.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.portal.Flatpak -Exec=@libexecdir@/flatpak-portal +Exec=@libexecdir@/flatpak-portal@extraargs@ SystemdService=flatpak-portal.service diff --git a/tests/Makefile-test-matrix.am.inc b/tests/Makefile-test-matrix.am.inc index e6d68970..b9fa0559 100644 --- a/tests/Makefile-test-matrix.am.inc +++ b/tests/Makefile-test-matrix.am.inc @@ -35,6 +35,7 @@ TEST_MATRIX_DIST= \ tests/test-unsigned-summaries.sh \ tests/test-update-remote-configuration.sh \ tests/test-override.sh \ + tests/test-update-portal.sh \ $(NULL) TEST_MATRIX_EXTRA_DIST= \ tests/test-run.sh \ diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc index 1974e870..af308b93 100644 --- a/tests/Makefile.am.inc +++ b/tests/Makefile.am.inc @@ -62,19 +62,31 @@ testcommon_SOURCES = tests/testcommon.c tests_httpcache_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS) $(APPSTREAM_GLIB_CFLAGS) \ -DFLATPAK_COMPILATION \ - -DLOCALEDIR=\"$(localedir)\" + -DLOCALEDIR=\"$(localedir)\" tests_httpcache_LDADD = $(AM_LDADD) $(BASE_LIBS) $(OSTREE_LIBS) $(SOUP_LIBS) $(JSON_LIBS) $(APPSTREAM_GLIB_LIBS) \ libflatpak-common.la libflatpak-common-base.la libglnx.la +tests_test_update_portal_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) \ + -DFLATPAK_COMPILATION \ + -DLOCALEDIR=\"$(localedir)\" +tests_test_update_portal_LDADD = $(AM_LDADD) $(BASE_LIBS) +tests_test_update_portal_SOURCES = \ + tests/test-update-portal.c \ + portal/flatpak-portal-dbus.c + tests/services/org.freedesktop.Flatpak.service: session-helper/org.freedesktop.Flatpak.service.in mkdir -p tests/services $(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(abs_top_builddir)|" $< > $@ +tests/services/org.freedesktop.portal.Flatpak.service: portal/org.freedesktop.portal.Flatpak.service.in + mkdir -p tests/services + $(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(abs_top_builddir)|" -e "s|\@extraargs\@| --poll-timeout=1|" $< > $@ + tests/services/org.freedesktop.Flatpak.SystemHelper.service: system-helper/org.freedesktop.Flatpak.SystemHelper.service.in mkdir -p tests/services $(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(abs_top_builddir)|" -e "s|\@extraargs\@| --session --no-idle-exit|" $< > $@ -tests/libtest.sh: tests/services/org.freedesktop.Flatpak.service tests/services/org.freedesktop.Flatpak.SystemHelper.service +tests/libtest.sh: tests/services/org.freedesktop.Flatpak.service tests/services/org.freedesktop.Flatpak.SystemHelper.service tests/services/org.freedesktop.portal.Flatpak.service install-test-data-hook: if ENABLE_INSTALLED_TESTS @@ -143,6 +155,7 @@ TEST_MATRIX_SOURCE = \ tests/test-update-remote-configuration.sh \ tests/test-override.sh \ tests/test-p2p-security.sh{user,collections+system,collections} \ + tests/test-update-portal.sh \ $(NULL) update-test-matrix: @@ -167,7 +180,7 @@ dist_test_scripts = ${TEST_MATRIX_DIST} dist_installed_test_extra_scripts += ${TEST_MATRIX_EXTRA_DIST} test_programs = testlibrary testcommon -test_extra_programs = tests/httpcache +test_extra_programs = tests/httpcache tests/test-update-portal @VALGRIND_CHECK_RULES@ VALGRIND_SUPPRESSIONS_FILES=tests/flatpak.supp tests/glib.supp diff --git a/tests/libtest.sh b/tests/libtest.sh index cd1d65a2..59c9dbe3 100644 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -335,6 +335,14 @@ run () { } +run_with_sandboxed_bus () { + BUSSOCK=$(mktemp ${test_tmpdir}/bus.XXXXXX) + rm -rf ${BUSSOCK} + run --command=socat --filesystem=${test_tmpdir} org.test.Hello unix-listen:${BUSSOCK} unix-connect:/run/user/`id -u`/bus & + while [ ! -e ${BUSSOCK} ]; do sleep 1; done + DBUS_SESSION_BUS_ADDRESS="unix:path=${BUSSOCK}" "$@" +} + run_sh () { ID=${1:-org.test.Hello} shift diff --git a/tests/make-test-runtime.sh b/tests/make-test-runtime.sh index 5f296cba..5d2c309b 100755 --- a/tests/make-test-runtime.sh +++ b/tests/make-test-runtime.sh @@ -60,7 +60,7 @@ add_bin() { fi } -for i in $@ bash ls cat echo readlink; do +for i in $@ bash ls cat echo readlink socat; do I=`which $i` add_bin $I done diff --git a/tests/test-update-portal.c b/tests/test-update-portal.c new file mode 100644 index 00000000..28f75777 --- /dev/null +++ b/tests/test-update-portal.c @@ -0,0 +1,198 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +#include <sys/stat.h> +#include <fcntl.h> + +#include <gio/gio.h> +#include "portal/flatpak-portal-dbus.h" + +GDBusConnection *connection; + +const char *portal_name = "org.freedesktop.portal.Flatpak"; +const char *portal_path = "/org/freedesktop/portal/Flatpak"; + +static PortalFlatpakUpdateMonitor * +create_monitor (PortalFlatpak *portal, + GCallback update_available_cb, + gpointer cb_data, + GError **error) +{ + static int counter = 1; + PortalFlatpakUpdateMonitor *monitor; + g_autofree char *token = NULL; + g_autofree char *monitor_path = NULL; + g_autofree char *sender = NULL; + g_autofree char *monitor_handle = NULL; + char *s; + GVariantBuilder opt_builder; + + sender = g_strdup (g_dbus_connection_get_unique_name (connection) + 1); + while ((s = strchr (sender, '.')) != NULL) + *s = '_'; + + token = g_strdup_printf ("test_token%d", counter++); + + monitor_path = g_strdup_printf ("/org/freedesktop/portal/Flatpak/update_monitor/%s/%s", sender, token); + monitor = portal_flatpak_update_monitor_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, + portal_name, monitor_path, + NULL, error); + if (monitor == NULL) + return NULL; + + if (update_available_cb) + g_signal_connect (monitor, "update-available", update_available_cb, cb_data); + + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token)); + + if (!portal_flatpak_call_create_update_monitor_sync (portal, + g_variant_builder_end (&opt_builder), + &monitor_handle, + NULL, error)) + return NULL; + + return monitor; +} + +static void +update_available (PortalFlatpakUpdateMonitor *object, + GVariant *arg_update_info, + gpointer user_data) +{ + const char *running, *local, *remote; + + g_variant_lookup (arg_update_info, "running-commit", "&s", &running); + g_variant_lookup (arg_update_info, "local-commit", "&s", &local); + g_variant_lookup (arg_update_info, "remote-commit", "&s", &remote); + + g_print ("update_available running=%s local=%s remote=%s\n", running, local, remote); +} + +static void +write_status (int res, int status_pipe) +{ + char c = res; + write (status_pipe, &c, 1); +} + +typedef int (*TestCallback) (PortalFlatpak *portal, int status_pipe); + +static int +monitor_test (PortalFlatpak *portal, int status_pipe) +{ + g_autoptr(GError) error = NULL; + PortalFlatpakUpdateMonitor *monitor; + GMainLoop *loop; + + monitor = create_monitor (portal, + (GCallback)update_available, NULL, + &error); + if (monitor == NULL) + { + g_printerr ("Error creating monitor: %s\n", error->message); + return 1; + } + + /* Return 0, to indicate we've successfully started monitor */ + write_status (0, status_pipe); + + g_print ("Entering main loop waiting for updates\n"); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + return 0; +} + +static int +run_test (int status_pipe, const char *pidfile, TestCallback test) +{ + g_autoptr(GError) error = NULL; + PortalFlatpak *portal; + g_autofree char *pid = NULL; + + pid = g_strdup_printf ("%d", getpid ()); + if (!g_file_set_contents (pidfile, pid, -1, &error)) + { + g_printerr ("Error creating pidfile: %s\n", error->message); + return 1; + } + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (connection == NULL) + { + g_printerr ("Error connecting: %s\n", error->message); + return 1; + } + + portal = portal_flatpak_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, + portal_name, portal_path, + NULL, &error); + if (portal == NULL) + { + g_printerr ("Error creating proxy: %s\n", error->message); + return 1; + } + + return test (portal, status_pipe); +} + + +int +main (int argc, char *argv[]) +{ + pid_t pid; + int pipes[2]; + TestCallback test_callback; + + if (argc < 2) + { + g_printerr ("No test command specified"); + return 1; + } + + if (strcmp (argv[1], "monitor") == 0) + test_callback = monitor_test; + else + { + g_printerr ("Unknown command %s specified", argv[1]); + return 1; + } + + if (pipe (pipes) != 0) + { + perror ("pipe:"); + return 1; + } + + pid = fork(); + if (pid == -1) + { + perror ("pipe:"); + return 1; + } + + if (pid != 0) + { + char c; + + /* parent */ + close (pipes[1]); + if (read (pipes[0], &c, 1) != 1) + return 1; + + return c; + } + else + { + int res; + + close (pipes[0]); + + res = run_test (pipes[1], argc > 2 ? argv[2] : "pid.out", test_callback); + /* If this returned early we have some setup failure, report it */ + write_status (res, pipes[1]); + exit (res); + } +} diff --git a/tests/test-update-portal.sh b/tests/test-update-portal.sh new file mode 100755 index 00000000..0d3b38e7 --- /dev/null +++ b/tests/test-update-portal.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Copyright (C) 2019 Colin Walters <walters@verbum.org> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +skip_without_bwrap + +echo "1..1" + +setup_repo +install_repo + +run_with_sandboxed_bus ${test_builddir}/test-update-portal monitor monitor.pid > update-monitor.out +MONITOR_PID=$(cat monitor.pid) + +OLD_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master) +make_updated_app +NEW_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master) + +for i in {15..1}; do + if grep -q -e "update_available .* remote=${NEW_COMMIT}" update-monitor.out; then + assert_file_has_content update-monitor.out "running=${OLD_COMMIT} local=${OLD_COMMIT} remote=${NEW_COMMIT}" + echo found update ${NEW_COMMIT} + break + fi + if [ $i == 1 ]; then + assert_not_reached "Timed out when looking for update 1" + fi + sleep 1 +done + +make_updated_app test "" master UPDATE2 + +NEWER_COMMIT=$(cat repos/test/refs/heads/app/org.test.Hello/$ARCH/master) + +for i in {15..1}; do + if grep -q -e "update_available .* remote=${NEWER_COMMIT}" update-monitor.out; then + assert_file_has_content update-monitor.out "running=${OLD_COMMIT} local=${OLD_COMMIT} remote=${NEWER_COMMIT}" + echo found update ${NEWER_COMMIT} + break + fi + if [ $i == 1 ]; then + assert_not_reached "Timed out when looking for update 2" + fi + sleep 1 +done + +# Make sure monitor is dead +kill -9 $MONITOR_PID + +echo "ok monitor updates" |