From fad37dfa8c64b575d4076eed35ac8e63cd296535 Mon Sep 17 00:00:00 2001 From: razzeee Date: Tue, 21 Apr 2026 09:22:52 +0200 Subject: [PATCH] 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. --- tests/meson.build | 1 + tests/test-upgrade-from-header.sh | 60 +++++++++++++++++++++++++++++++ tests/web-server.py | 21 +++++++++-- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tests/test-upgrade-from-header.sh diff --git a/tests/meson.build b/tests/meson.build index ed04e380..43d1493b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -409,6 +409,7 @@ tests = { 'extra-data': {'wrap': ['user', 'system']}, 'preinstall': {}, 'run-custom': {'wrap': ['user', 'system']}, + 'upgrade-from-header': {'wrap': ['user', 'system', 'system-norevokefs']}, } wrapped_tests = [] diff --git a/tests/test-upgrade-from-header.sh b/tests/test-upgrade-from-header.sh new file mode 100644 index 00000000..7bef9f3d --- /dev/null +++ b/tests/test-upgrade-from-header.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +set -euo pipefail + +. "$(dirname "$0")"/libtest.sh + +skip_without_bwrap +skip_revokefs_without_fuse + +echo "1..4" + +# Override the httpd function to enable header logging before setup_repo calls +# it. The web-server.py will log Flatpak-Ref and Flatpak-Upgrade-From headers +# to httpd-headers-log. +httpd () { + if [ $# -eq 0 ] ; then + set web-server.py repos "$(pwd)"/httpd-headers-log + fi + + COMMAND=$1 + shift + + rm -f httpd-pipe + mkfifo httpd-pipe + PYTHONUNBUFFERED=1 "$(dirname "$0")"/$COMMAND "$@" 3> httpd-pipe 2>&1 | tee -a httpd-log >&2 & + read < httpd-pipe +} + +touch httpd-headers-log + +setup_repo + +truncate -s 0 httpd-headers-log + +install_repo + +APP_REF="app/org.test.Hello/${ARCH}/master" + +assert_not_file_has_content httpd-headers-log "Flatpak-Upgrade-From" + +ok "no Flatpak-Upgrade-From header on fresh install" + +assert_file_has_content httpd-headers-log "Flatpak-Ref: ${APP_REF}" + +ok "Flatpak-Ref header sent on fresh install" + +INSTALLED_COMMIT=$(${FLATPAK} ${U} info --show-commit org.test.Hello) + +make_updated_app +truncate -s 0 httpd-headers-log + +${FLATPAK} ${U} update -y org.test.Hello >&2 + +assert_file_has_content httpd-headers-log "Flatpak-Upgrade-From: ${INSTALLED_COMMIT}" + +ok "Flatpak-Upgrade-From header sent with correct commit hash on update" + +assert_file_has_content httpd-headers-log "Flatpak-Ref: ${APP_REF}" + +ok "Flatpak-Ref header sent on update" diff --git a/tests/web-server.py b/tests/web-server.py index 9dd82f17..8ef04773 100755 --- a/tests/web-server.py +++ b/tests/web-server.py @@ -15,6 +15,8 @@ from io import BytesIO import sys class RequestHandler(http_server.SimpleHTTPRequestHandler): + headers_log_file = None + def handle_tokens(self): need_token_path = self.translate_path(self.path) + ".need_token" if os.path.isfile(need_token_path): @@ -34,14 +36,26 @@ class RequestHandler(http_server.SimpleHTTPRequestHandler): return True return False + def log_flatpak_headers(self): + if self.headers_log_file is None: + return + + for name in ("Flatpak-Ref", "Flatpak-Upgrade-From", "Flatpak-Is-Update"): + value = self.headers.get(name) + if value is not None: + with open(self.headers_log_file, 'a+') as f: + f.write("%s: %s\n" % (name, value)) + def do_GET(self): + self.log_flatpak_headers() if self.handle_tokens(): return None self.headers.__delitem__("If-Modified-Since") return super().do_GET() -def run(dir): +def run(dir, headers_log=None): RequestHandler.protocol_version = "HTTP/1.0" + RequestHandler.headers_log_file = headers_log httpd = http_server.HTTPServer( ("127.0.0.1", 0), RequestHandler) host, port = httpd.socket.getsockname()[:2] with open("httpd-port", 'w') as file: @@ -59,7 +73,10 @@ def run(dir): if __name__ == '__main__': dir = None + headers_log = None if len(sys.argv) >= 2 and len(sys.argv[1]) > 0: dir = sys.argv[1] + if len(sys.argv) >= 3 and len(sys.argv[2]) > 0: + headers_log = sys.argv[2] - run(dir) + run(dir, headers_log)