summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2019-09-27 16:39:58 +0200
committerAlexander Larsson <alexander.larsson@gmail.com>2019-10-02 14:57:11 +0200
commitc15c1946ff7f8143e32519e1eb8014edf9d7dbfa (patch)
tree59528641da0ecea214ec72e8100aedab5e7145d6
parent82328bee85165aba4deb6ef118e74733aec5f1a5 (diff)
downloadflatpak-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--.gitignore1
-rw-r--r--portal/org.freedesktop.portal.Flatpak.service.in2
-rw-r--r--tests/Makefile-test-matrix.am.inc1
-rw-r--r--tests/Makefile.am.inc19
-rw-r--r--tests/libtest.sh8
-rwxr-xr-xtests/make-test-runtime.sh2
-rw-r--r--tests/test-update-portal.c198
-rwxr-xr-xtests/test-update-portal.sh69
8 files changed, 295 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index 82418720..77d6f526 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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"