mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-26 22:22:22 +00:00
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.
This commit is contained in:
parent
82328bee85
commit
c15c1946ff
1
.gitignore
vendored
1
.gitignore
vendored
@ -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.*
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
198
tests/test-update-portal.c
Normal file
198
tests/test-update-portal.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
69
tests/test-update-portal.sh
Executable file
69
tests/test-update-portal.sh
Executable file
@ -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"
|
||||
Loading…
x
Reference in New Issue
Block a user