Files
flatpak/tests/meson.build
razzeee fad37dfa8c tests: add test for Flatpak-Upgrade-From header on install vs update
Add an integration test that verifies the Flatpak-Upgrade-From HTTP
header is correctly sent during update operations but absent during
fresh installs. This header is used by Flathub to distinguish updates
from new installs in download statistics.

To support the test, extend web-server.py to optionally log Flatpak-*
request headers to a separate file.
2026-04-21 11:28:31 +00:00

497 lines
12 KiB
Meson

# Copyright 2022 Collabora Ltd.
# SPDX-License-Identifier: LGPL-2.1-or-later
installed_testdir = get_option('prefix') / get_option('libexecdir') / 'installed-tests' / 'Flatpak'
installed_tests_metadir = get_option('prefix') / get_option('datadir') / 'installed-tests' / 'Flatpak'
if get_option('system_bubblewrap') == ''
env_flatpak_bwrap = project_build_root / 'subprojects' / 'bubblewrap' / 'flatpak-bwrap'
else
env_flatpak_bwrap = get_option('system_bubblewrap')
endif
if get_option('system_dbus_proxy') == ''
env_flatpak_dbusproxy = project_build_root / 'subprojects' / 'dbus-proxy' / 'flatpak-dbus-proxy'
else
env_flatpak_dbusproxy = get_option('system_dbus_proxy')
endif
tests_environment = {
'FLATPAK_CONFIG_DIR' : '/dev/null',
'FLATPAK_DATA_DIR' : '/dev/null',
'FLATPAK_PORTAL' : project_build_root / 'portal' / 'flatpak-portal',
'FLATPAK_REVOKEFS_FUSE' : project_build_root / 'revokefs' / 'revokefs-fuse',
'FLATPAK_TESTS_DEBUG' : '1',
'FLATPAK_TESTS_STRICT_TAP' : '1',
'FLATPAK_TRIGGERSDIR' : project_source_root / 'triggers',
'FLATPAK_VALIDATE_ICON' : project_build_root / 'icon-validator' / 'flatpak-validate-icon',
'FUSERMOUNT' : fusermount,
'G_TEST_BUILDDIR' : meson.current_build_dir(),
'G_TEST_SRCDIR' : meson.current_source_dir(),
'FLATPAK_BWRAP' : env_flatpak_bwrap,
'FLATPAK_DBUSPROXY' : env_flatpak_dbusproxy,
}
tests_environment_prepend = {
'GI_TYPELIB_PATH' : project_build_root / 'common',
'LD_LIBRARY_PATH' : project_build_root / 'common',
'PATH' : project_build_root / 'app',
}
lsan_options = 'log_threads=1:suppressions=' + meson.current_source_dir() / 'flatpak-asan.supp'
if get_option('installed_tests')
configure_file(
input : 'installed-tests.sh.in',
output : 'installed-tests.sh',
configuration : {
'FUSERMOUNT' : fusermount,
'FLATPAK_TRIGGERSDIR' : get_option('prefix') / get_option('datadir') / 'flatpak' / 'triggers',
},
install_dir : installed_testdir,
)
endif
# Explicitly doing a find_program() for this avoids lots of output with
# older Meson versions
tap_test = find_program(
files(project_source_root / 'buildutil/tap-test'),
)
if can_run_host_binaries
runtime_repo = custom_target(
'runtime-repo',
build_by_default : false,
command : [
files('make-runtime-repos'),
project_build_root / 'app',
files('make-test-runtime.sh'),
project_build_root / 'tests/runtime-repo',
'@OUTPUT@',
],
depends : [flatpak_exe],
output : 'runtime-repo.stamp',
)
endif
libtestlib = static_library(
'testlib',
'testlib.c',
include_directories : [common_include_directories],
dependencies : [
base_deps,
libglnx_dep,
],
install : false,
)
libtestlib_dep = declare_dependency(
dependencies : [
base_deps,
libglnx_dep,
],
include_directories : [common_include_directories],
link_with : libtestlib,
)
c_tests = [
['testapp', {
'extra_dependencies' : [
libflatpak_app_dep,
],
}],
['testcommon', {}],
['testlibrary', {
'dependencies' : [
base_deps,
fuse_dep,
libflatpak_dep,
libglnx_dep,
libostree_dep,
],
'extra_sources' : [
'can-use-fuse.c',
'testlib.c',
],
'timeout' : 150,
}],
['test-context', {}],
['test-exports', {}],
['test-instance', {
'extra_dependencies' : [
libglnx_testlib_dep,
],
}],
['test-locale-utils', {}],
['test-portal', {
'extra_sources' : [
portal_gdbus[0],
portal_gdbus[1],
],
}],
]
foreach testcase : c_tests
name = testcase[0]
options = testcase[1]
exe = executable(
name,
dependencies : options.get('dependencies', [
base_deps,
appstream_dep,
json_glib_dep,
libflatpak_common_dep,
libflatpak_common_base_dep,
libglnx_dep,
libostree_dep,
libtestlib_dep,
] + options.get('extra_dependencies', [])),
sources : [name + '.c'] + options.get('extra_sources', []),
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
if get_option('installed_tests')
configure_file(
input : 'tap.test.in',
output : name + '.test',
configuration : {
'basename' : name,
'installed_testdir' : installed_testdir,
'wrapper' : '',
},
install_dir : installed_tests_metadir,
)
endif
test_env = environment(tests_environment)
foreach k, v: tests_environment_prepend
test_env.prepend(k, v)
endforeach
lsan_log_path = ':log_path=' + meson.current_build_dir() / \
'asan_' + name.underscorify() + '.log'
test_env.set('LSAN_OPTIONS', lsan_options + lsan_log_path)
if can_run_host_binaries
test(
name,
tap_test,
args : [exe],
depends : runtime_repo,
env : test_env,
protocol : 'tap',
timeout : options.get('timeout', 30),
)
endif
endforeach
executable(
'hold-lock',
'hold-lock.c',
dependencies : [
base_deps,
libglnx_dep,
],
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'httpcache',
'httpcache.c',
dependencies : [
base_deps,
json_glib_dep,
libflatpak_common_dep,
libflatpak_common_base_dep,
libglnx_dep,
libostree_dep,
],
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'mock-flatpak',
'mock-flatpak.c',
dependencies : [
base_deps,
appstream_dep,
json_glib_dep,
libflatpak_app_dep,
libflatpak_common_dep,
libflatpak_common_base_dep,
libtestlib_dep,
libglnx_dep,
libostree_dep,
],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'test-update-portal',
sources : [
'test-update-portal.c',
] + portal_gdbus,
dependencies : base_deps,
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'test-portal-impl',
'test-portal-impl.c',
dependencies : base_deps,
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'test-authenticator',
'test-authenticator.c',
dependencies : [
base_deps,
libflatpak_common_dep,
libflatpak_common_base_dep,
libglnx_dep,
],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
executable(
'try-syscall',
'try-syscall.c',
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
override_options: ['b_sanitize=none'],
)
executable(
'list-unused',
'list-unused.c',
dependencies : [
base_deps,
libflatpak_common_dep,
libflatpak_common_base_dep,
libglnx_dep,
libostree_dep,
],
include_directories : [common_include_directories],
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
if cc.links('#include <stdio.h>\nint main(void) { printf("test"); return 0; }',
args: ['-static'],
name: 'static libc')
executable(
'apply-extra-static',
'apply-extra-static.c',
install : get_option('installed_tests'),
install_dir : installed_testdir,
override_options : ['b_sanitize=none'],
link_args : ['-static'],
)
else
warning('static libc not available, apply-extra-static will be skipped')
endif
subdir('share/xdg-desktop-portal/portals')
subdir('services')
subdir('test-keyring')
subdir('test-keyring2')
configure_file(
input : 'package_version.txt.in',
output : 'package_version.txt',
configuration : {
'PACKAGE_VERSION' : meson.project_version(),
},
install : get_option('installed_tests'),
install_dir : installed_testdir,
)
if get_option('installed_tests')
subdir('installed-services')
install_data(
'http-utils-test-server.py',
'make-multi-collection-id-repo.sh',
'make-test-app.sh',
'make-test-runtime.sh',
'oci-registry-client.py',
'oci-registry-server.py',
'test-webserver.sh',
'test-wrapper.sh',
'web-server.py',
install_dir : installed_testdir,
install_mode : 'rwxr-xr-x',
)
install_data(
'gphoto2-list',
'libtest.sh',
'org.flatpak.Authenticator.test.service.in',
'org.freedesktop.impl.portal.desktop.test.service.in',
'org.test.Hello.png',
'session.conf.in',
'test.filter',
'test.portal.in',
install_dir : installed_testdir,
install_mode : 'rw-r--r--',
)
endif
shared_module(
'preload',
'libpreload.c',
install : get_option('installed_tests'),
install_dir : installed_testdir,
override_options: ['b_sanitize=none'],
)
tests = {
'basic': {},
'completion': {},
'config': {},
'build-update-repo': {},
'http-utils': {},
'run': {'wrap': [
'user,nodeltas',
'user,deltas',
'system,nodeltas',
'system,deltas',
'system-norevokefs,nodeltas',
'system-norevokefs,deltas',
]},
'info': {'wrap': ['user', 'system']},
'repo': {'wrap': [
'user',
'system',
'system-norevokefs',
'user,oldsummary',
'system,oldsummary',
]},
'history': {},
'sideload': {'wrap': ['user', 'system']},
'default-remotes': {},
'metadata-validation': {},
'extensions': {},
'extension-branch-follow': {},
'bundle': {'wrap': ['user', 'system', 'system-norevokefs']},
'oci': {},
'oci-registry': {'wrap': [
'user,http',
'user,https',
'system,http',
'system,https',
]},
'update-remote-configuration': {'wrap': ['newsummary', 'oldsummary']},
'override': {},
'update-portal': {'wrap': ['user', 'system']},
'auth': {},
'unused': {},
'summaries': {'wrap': ['user', 'system']},
'subset': {'wrap': ['user', 'system']},
'prune': {},
'seccomp': {},
'repair': {},
'extra-data': {'wrap': ['user', 'system']},
'preinstall': {},
'run-custom': {'wrap': ['user', 'system']},
'upgrade-from-header': {'wrap': ['user', 'system', 'system-norevokefs']},
}
wrapped_tests = []
foreach name, testcase : tests
script = 'test-@0@.sh'.format(name)
if not testcase.has_key('wrap')
wrapped_tests += {'name': script, 'script': script}
continue
endif
foreach wrap : testcase['wrap']
wrapped_tests += {
'name': 'test-@0@@@1@.wrap'.format(name, wrap),
'script': script,
}
endforeach
endforeach
foreach testcase : wrapped_tests
name = testcase['name']
script = testcase.get('script', name)
timeout = {
'test-bundle.sh' : 60,
'test-oci-registry.sh' : 60,
'test-repo.sh' : 300,
'test-run.sh' : 90,
'test-summaries.sh' : 60,
'test-unused.sh' : 90,
'test-update-portal.sh' : 90,
'test-extra-data.sh' : 90,
}.get(script, 30)
is_parallel = {
'test-history.sh' : false,
}.get(script, true)
if get_option('installed_tests')
if name == script
wrapper = ''
else
wrapper = installed_testdir / 'test-wrapper.sh'
endif
install_data(
script,
install_dir : installed_testdir,
install_mode : 'rwxr-xr-x',
)
configure_file(
input : 'tap.test.in',
output : name + '.test',
configuration : {
'basename' : name,
'installed_testdir' : installed_testdir,
'wrapper' : wrapper,
},
install_dir : installed_tests_metadir,
)
endif
test_env = environment(tests_environment)
foreach k, v: tests_environment_prepend
test_env.prepend(k, v)
endforeach
lsan_log_path = ':log_path=' + meson.current_build_dir() / \
'asan_' + name.underscorify() + '.log'
test_env.set('LSAN_OPTIONS', lsan_options + lsan_log_path)
if can_run_host_binaries
test(
name,
tap_test,
args : [meson.current_source_dir() / name],
depends : runtime_repo,
env : test_env,
is_parallel : is_parallel,
protocol : 'tap',
timeout : timeout,
)
endif
endforeach