#!/usr/bin/env bats # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2026 Bryan Joshua Pedini # E2E: AUR packages. pacman backend (archlinux): su-dummy-aur 1.0 is a foreign package (fixture # FIXTURE_AUR=1), the fake paru (fixtures/fake-paru.sh) offers it at 2.0 and installs it through # the fake sudo (fixtures/fake-sudo.sh: su, passwordless for wheel). The applet runs either as the # test user su-tester, re-executing itself through that sudo, or as root with SUDO_USER=su-tester # (what the re-exec leaves behind). Rows: [1] su-dummy-a [2]* su-dummy-aur [3] su-dummy-b # [4] su-dummy-c. Other backends: the marker column is a space and no AUR helper ever runs. load helpers PARU_LOG=/tmp/su-aur-paru.log AUR_OLD=/srv/su-aur/su-dummy-aur-1.0-1-any.pkg.tar.zst setup_file() { e2e_setup_file if [[ $BE == pacman ]]; then install -m 0755 "$BATS_TEST_DIRNAME/fixtures/fake-paru.sh" /usr/local/bin/paru install -m 0755 "$BATS_TEST_DIRNAME/fixtures/fake-sudo.sh" /usr/local/bin/sudo else # a paru that only records that it ran (it never may: AUR helpers are for pacman only) printf '#!/bin/sh\necho "$*" >>%s\n' "$PARU_LOG" >/usr/local/bin/paru chmod 0755 /usr/local/bin/paru fi } teardown_file() { rm -f /usr/local/bin/paru "$PARU_LOG" if [[ $BE == pacman ]]; then rm -f /usr/local/bin/sudo; fi } setup() { e2e_reset if [[ $BE == pacman ]]; then pacman -U --noconfirm "$AUR_OLD" >/dev/null 2>&1 [[ $(pkg_ver su-dummy-aur) == 1.0 ]] fi : >"$PARU_LOG" chmod 0666 "$PARU_LOG" } # as_tester ARGS...: run skeptical-updater as the unprivileged su-tester (its TMPDIR: the suite's # is root's); a run that needs root re-executes itself through the fake sudo as_tester() { runuser -u su-tester -- env TMPDIR=/tmp HOME=/home/su-tester skeptical-updater "$@"; } pacman_only() { [[ $BE == pacman ]] || skip "pacman backend only"; } @test "AUR: the row is listed with * and repo aur; paru ran as the invoking user after the sudo re-exec" { pacman_only run as_tester list assert_success assert_line --index 0 "Backend: pacman ($(pretty_name)) + AUR via paru" assert_line 'Refreshing package lists... done.' assert_line '4 upgradable, 0 trusted (hidden, use --all to show), 4 to review:' assert_line ' [1] su-dummy-a 1.0-1 -> 2.0-1 su-dummy' assert_line ' [2]* su-dummy-aur 1.0-1 -> 2.0-1 aur' assert_line ' [3] su-dummy-b 1.0-1 -> 2.0-1 su-dummy' assert_line ' [4] su-dummy-c 1.0-1 -> 2.0-1 su-dummy' run cat "$PARU_LOG" assert_output 'su-tester HOME=/home/su-tester PWD=/home/su-tester -Qua' } @test "AUR: N? and N?? on the AUR row (pacman -Qi; merged with paru -Sia)" { pacman_only SUDO_USER=su-tester run skeptical-updater --no-refresh <<<$'2?\n2??\nq' assert_success assert_output --partial "$(printf '%s\n' \ 'su-dummy-aur: Skeptical-updater dummy package AUR (foreign: in no repository)' \ 'reason: explicitly installed' \ 'required by: nothing')" assert_line '# lines starting with * come from the upstream candidate: a differing value, or a field the installed record lacks' assert_output --partial "$(printf '%s\n' ' Version : 1.0-1' '* Version : 2.0-1' '* Repository : aur')" assert_line ' Install Reason : Explicitly installed' assert_output --partial "$(printf '%s\n' ' URL : https://example.invalid/su-dummy' '* AUR URL : https://aur.archlinux.org/packages/su-dummy-aur')" assert_output --partial "$(printf '%s\n' ' Packager : su-fixture ' '* Maintainer : su-fixture')" assert_output --partial "$(printf '%s\n' ' Validated By : None' '* Votes : 7' '* Popularity : 0.01' '* Out Of Date : No')" run grep -c 'su-tester HOME=/home/su-tester PWD=/home/su-tester -Sia su-dummy-aur' "$PARU_LOG" assert_output 1 } @test "AUR: N- keeps su-dummy-aur at 1.0 while the repository packages upgrade; paru is not run" { pacman_only SUDO_USER=su-tester run skeptical-updater <<<$'2-\n' assert_success assert_line 'Excluded from this run: su-dummy-aur' assert_line 'Upgrade finished.' [[ $(versions) == "a=2.0 b=2.0 c=2.0" ]] || fail "versions after the run: $(versions)" [[ $(pkg_ver su-dummy-aur) == 1.0 ]] || fail "su-dummy-aur: $(pkg_ver su-dummy-aur)" run grep -c -- '-Sua' "$PARU_LOG" assert_output 0 } @test "AUR: a plain upgrades su-dummy-aur to 2.0 with paru, after the repository packages" { pacman_only run as_tester <<<'' assert_success assert_line 'Excluded from this run: none' assert_line '+ runuser -u su-tester -- env HOME=/home/su-tester paru -Sua --noconfirm' assert_line 'Upgrade finished.' [[ $(versions) == "a=2.0 b=2.0 c=2.0" ]] || fail "versions after the run: $(versions)" [[ $(pkg_ver su-dummy-aur) == 2.0 ]] || fail "su-dummy-aur: $(pkg_ver su-dummy-aur)" # the repository step came first: su-dummy-a was 2.0 already when paru -Sua started run grep -A1 -- ' -Sua --noconfirm$' "$PARU_LOG" assert_line --index 0 'su-tester HOME=/home/su-tester PWD=/home/su-tester -Sua --noconfirm' assert_line --index 1 ' (at -Sua: su-dummy-a 2.0-1)' run skeptical-updater list --no-refresh --no-aur assert_output --partial 'Nothing to upgrade.' SUDO_USER=su-tester run skeptical-updater list --no-refresh assert_output --partial 'Nothing to upgrade.' } @test "AUR: only the AUR row left to upgrade: pacman is not run, only paru" { pacman_only # (the files only: `..` changes with the db.lck of paru's pacman -U) before=$(ls -l --time-style=full-iso /var/lib/pacman/sync) SUDO_USER=su-tester run skeptical-updater <<<$'1- 3- 4-\n' assert_success assert_line 'No repository package to upgrade: pacman is not run, only paru.' assert_line '+ runuser -u su-tester -- env HOME=/home/su-tester paru -Sua --noconfirm --ignore su-dummy-a,su-dummy-b,su-dummy-c' refute_line --regexp '^\+ pacman ' [[ $(versions) == "a=1.0 b=1.0 c=1.0" ]] || fail "versions after the run: $(versions)" [[ $(pkg_ver su-dummy-aur) == 2.0 ]] || fail "su-dummy-aur: $(pkg_ver su-dummy-aur)" [[ $(ls -l --time-style=full-iso /var/lib/pacman/sync) == "$before" ]] || fail "the sync database changed although pacman was not run" } @test "AUR: --dry-run prints paru's command line (as the invoking user) and changes nothing" { pacman_only SUDO_USER=su-tester run skeptical-updater --dry-run --no-refresh <<<$'3-\n' assert_success assert_line '+ pacman -Su --noconfirm --ignore su-dummy-b' assert_line '+ runuser -u su-tester -- env HOME=/home/su-tester paru -Sua --noconfirm --ignore su-dummy-b' assert_line 'Dry run: nothing was changed.' [[ $(versions) == "a=1.0 b=1.0 c=1.0" && $(pkg_ver su-dummy-aur) == 1.0 ]] run grep -c -- '-Sua' "$PARU_LOG" assert_output 0 } @test "AUR: unprivileged list --no-refresh runs paru directly, as that user" { pacman_only run as_tester list --no-refresh assert_success assert_line ' [2]* su-dummy-aur 1.0-1 -> 2.0-1 aur' run cat "$PARU_LOG" assert_output --regexp '^su-tester HOME=/home/su-tester PWD=[^ ]+ -Qua$' } @test "AUR: a root login (no SUDO_USER): skipped with a warning, the repository rows listed, paru never run" { pacman_only run skeptical-updater list --no-refresh assert_success assert_line --index 0 "Backend: pacman ($(pretty_name))" assert_line --index 1 'skeptical-updater: warning: aur: paru is never run as root and there is no invoking user (SUDO_USER is not set): AUR packages are neither listed nor upgraded (run skeptical-updater through sudo from your own account, or use --no-aur)' assert_line '3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:' refute_output --partial 'su-dummy-aur' [[ ! -s $PARU_LOG ]] } @test "AUR: --no-aur lists the repository rows only and never runs paru" { pacman_only run as_tester --no-aur list --no-refresh assert_success assert_line --index 0 "Backend: pacman ($(pretty_name))" assert_line ' [1] su-dummy-a 1.0-1 -> 2.0-1 su-dummy' refute_output --partial 'su-dummy-aur' [[ ! -s $PARU_LOG ]] } @test "other backends: the marker column is a space; no AUR helper is ever run, --aur-helper is ignored" { [[ $BE != pacman ]] || skip "not the pacman backend" run skeptical-updater list --no-refresh assert_success assert_line --regexp '^ \[1\] su-dummy-a +1\.0(-1)? +-> +2\.0(-1)? +[^ ]+$' run skeptical-updater --aur-helper=paru list --no-refresh assert_success assert_line "skeptical-updater: warning: --aur-helper=paru is ignored: AUR helpers only apply to the pacman backend (Arch Linux and derivatives)" assert_line --regexp '^ \[3\] su-dummy-c ' run skeptical-updater --dry-run --no-refresh <<<'' assert_success refute_output --partial 'paru' [[ ! -s $PARU_LOG ]] || fail "paru ran: $(cat "$PARU_LOG")" }