When stdin is a terminal the prompt is read with bash's readline, `IFS= read -e -r -p '> ' REPLY`, so the arrow keys no longer print escape garbage: Left/Right, Home/End, Ctrl-A/E, Backspace/Delete edit the line, and Up/Down walk the lines entered in this session (`history -s` for every line with a non-blank character; empty lines are not recorded). Down past the newest entry restores the line typed before Up, and Up at the oldest entry or Down on the new line ring the bell, as readline does by default. The Nx y/N answer is read the same way and never recorded. Nothing persists: HISTFILE is unset at startup and the history is never read or written. Verified on bash 4.3.48 and 5.2.15 that `read -e` and `history -s` share one history list in a non-interactive shell, that inherited HISTSIZE/HISTCONTROL/HISTIGNORE have no effect there, and that Ctrl-C at the prompt restores the terminal. readline draws the prompt on stderr, as bash does. Piped stdin keeps the plain `read -r` exactly, including the echo of each line and EOF => exit 2. New unit tests (tests/unit/lineedit.bats) drive a real pty with script(1): history recall, the bell at both ends, the stashed line, Left-arrow editing, the y/N answer kept out of the history, no history file under HOME/TMPDIR, ^D => exit 2. The E2E suite gets a pty smoke test (Up recalls 1?), skipped where the image has no script(1).
407 lines
17 KiB
Bash
407 lines
17 KiB
Bash
#!/usr/bin/env bats
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright (C) 2026 Bryan Joshua Pedini
|
|
|
|
# E2E: skeptical-updater against the REAL package manager of the container
|
|
# (apt, pacman, dnf or zypper), on the su-dummy-{a,b,c} fixture: 1.0 installed,
|
|
# 2.0 available, su-dummy-a depends on su-dummy-b. Every test starts from that
|
|
# state (e2e_reset) with no statefile and no holds/locks.
|
|
|
|
load helpers
|
|
|
|
setup_file() { e2e_setup_file; }
|
|
setup() { e2e_reset; }
|
|
|
|
# shellcheck source=/dev/null
|
|
zypper_verb() { case $(. /etc/os-release && printf '%s' "$ID") in opensuse-tumbleweed | opensuse-slowroll) echo dist-upgrade ;; *) echo update ;; esac; }
|
|
|
|
@test "banner shows the detected backend and the distro, refresh succeeds" {
|
|
run skeptical-updater list
|
|
assert_success
|
|
assert_line --index 0 "Backend: $BE ($(pretty_name))"
|
|
assert_line --index 1 "Refreshing package lists... done."
|
|
}
|
|
|
|
@test "list shows exactly the three dummies 1.0 -> 2.0" {
|
|
run skeptical-updater list --no-refresh
|
|
assert_success
|
|
assert_line "3 upgradable, 0 trusted (hidden, use --all to show), 3 to review:"
|
|
assert_line --regexp '^ \[1\] su-dummy-a +1\.0(-1)? +-> +2\.0(-1)? +[^ ]+$'
|
|
assert_line --regexp '^ \[2\] su-dummy-b +1\.0(-1)? +-> +2\.0(-1)? +[^ ]+$'
|
|
assert_line --regexp '^ \[3\] su-dummy-c +1\.0(-1)? +-> +2\.0(-1)? +[^ ]+$'
|
|
refute_line --regexp '^.\[4\]'
|
|
}
|
|
|
|
@test "N? prints the description, the install reason and who requires it" {
|
|
local -a lines_=()
|
|
local i a=-1 b=-1
|
|
run skeptical-updater --no-refresh <<<$'1?\n2?\nq'
|
|
assert_success
|
|
assert_line --regexp '^su-dummy-a: .*([Dd]ummy|skeptical-updater).*$'
|
|
assert_line --regexp '^su-dummy-b: .*([Dd]ummy|skeptical-updater).*$'
|
|
# [1] su-dummy-a was installed explicitly and nothing needs it; [2] su-dummy-b was installed as
|
|
# a dependency of su-dummy-a - the two lines right under each description, no indentation
|
|
mapfile -t lines_ <<<"$output"
|
|
for i in "${!lines_[@]}"; do
|
|
case ${lines_[i]} in
|
|
'su-dummy-a: '*) a=$i ;;
|
|
'su-dummy-b: '*) b=$i ;;
|
|
esac
|
|
done
|
|
[[ ${lines_[a + 1]} == 'reason: explicitly installed' && ${lines_[a + 2]} == 'required by: nothing' ]] ||
|
|
fail "1? (su-dummy-a): got '${lines_[a + 1]}' / '${lines_[a + 2]}'"
|
|
[[ ${lines_[b + 1]} == 'reason: installed as a dependency' && ${lines_[b + 2]} == 'required by: su-dummy-a' ]] ||
|
|
fail "2? (su-dummy-b): got '${lines_[b + 1]}' / '${lines_[b + 2]}'"
|
|
refute_output --partial 'required by (installed)'
|
|
assert_line 'Quit: nothing was upgraded.'
|
|
}
|
|
|
|
@test "N?? prints the native full info" {
|
|
run skeptical-updater --no-refresh <<<$'1??\nq'
|
|
assert_success
|
|
assert_line --regexp '^(Package: su-dummy-a|Name +: su-dummy-a)$'
|
|
}
|
|
|
|
@test "N+ writes the user row and the dep row; list hides both and counts them" {
|
|
run skeptical-updater --no-refresh <<<$'1+\nq'
|
|
assert_success
|
|
assert_line 'trusted su-dummy-a (+1 dependency: su-dummy-b)'
|
|
[[ -f $STATE_FILE ]]
|
|
[[ $(stat -c %a "$STATE_DIR") == 755 ]]
|
|
run cat "$STATE_FILE"
|
|
assert_line --index 0 '# skeptical-updater trusted packages. Columns: backend package reason added(UTC ISO-8601)'
|
|
assert_line --index 1 --regexp "^$BE"$'\t'"su-dummy-a"$'\t'"user"$'\t''[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]{8}Z$'
|
|
assert_line --index 2 --regexp "^$BE"$'\t'"su-dummy-b"$'\t'"dep:su-dummy-a"$'\t''[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]{8}Z$'
|
|
run skeptical-updater list --no-refresh
|
|
assert_success
|
|
assert_line "3 upgradable, 2 trusted (hidden, use --all to show), 1 to review:"
|
|
refute_output --partial 'su-dummy-a'
|
|
refute_output --partial 'su-dummy-b'
|
|
assert_line --regexp '^ \[1\] su-dummy-c '
|
|
run skeptical-updater list --no-refresh --all
|
|
assert_success
|
|
assert_line "3 upgradable, 2 trusted (marked with =), 1 to review:"
|
|
assert_line --regexp '^=\[1\] su-dummy-a '
|
|
assert_line --regexp '^=\[2\] su-dummy-b '
|
|
assert_line --regexp '^ \[3\] su-dummy-c '
|
|
}
|
|
|
|
@test "trust / trusted / refresh / untrust from the command line" {
|
|
run skeptical-updater trust su-dummy-a
|
|
assert_success
|
|
assert_output 'trusted su-dummy-a (+1 dependency: su-dummy-b)'
|
|
run skeptical-updater trusted
|
|
assert_success
|
|
assert_line --partial "$BE"$'\t'"su-dummy-a"$'\t'"user"$'\t'
|
|
assert_line --partial "$BE"$'\t'"su-dummy-b"$'\t'"dep:su-dummy-a"$'\t'
|
|
# refresh recomputes the closure: a removed dep row comes back
|
|
sed -i '/dep:su-dummy-a/d' "$STATE_FILE"
|
|
run skeptical-updater refresh
|
|
assert_success
|
|
assert_output 'refreshed the dependency closures of 1 trusted root: 1 added, 0 removed'
|
|
run grep -c $'\tdep:su-dummy-a\t' "$STATE_FILE"
|
|
assert_output 1
|
|
run skeptical-updater untrust su-dummy-a
|
|
assert_success
|
|
assert_output 'untrusted su-dummy-a (2 rows removed)'
|
|
run skeptical-updater trusted
|
|
assert_success
|
|
assert_output '# skeptical-updater trusted packages. Columns: backend package reason added(UTC ISO-8601)'
|
|
}
|
|
|
|
@test "excluding su-dummy-b (2- then enter) upgrades the others" {
|
|
before=$(holds_snapshot)
|
|
run skeptical-updater <<<$'2-\n'
|
|
assert_success
|
|
assert_line 'excluded from this run: su-dummy-b'
|
|
assert_line 'Excluded from this run: su-dummy-b'
|
|
assert_line 'Upgrade finished.'
|
|
[[ $(versions) == "a=2.0 b=1.0 c=2.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ $(holds_snapshot) == "$before" ]] || fail "hold/lock state changed: $(holds_snapshot)"
|
|
run skeptical-updater list --no-refresh
|
|
assert_line --regexp '^ \[1\] su-dummy-b +1\.0'
|
|
}
|
|
|
|
@test "a pre-existing hold/lock/IgnorePkg on su-dummy-c survives a run that excludes su-dummy-b" {
|
|
hold_c
|
|
before=$(holds_snapshot)
|
|
[[ -n $before ]]
|
|
run skeptical-updater list --no-refresh
|
|
assert_line --regexp '^ \[2\] su-dummy-b '
|
|
run skeptical-updater <<<$'2-\n'
|
|
assert_success
|
|
assert_line 'Excluded from this run: su-dummy-b'
|
|
[[ $(versions) == "a=2.0 b=1.0 c=1.0" ]] || fail "versions after the run: $(versions)"
|
|
after=$(holds_snapshot)
|
|
[[ $after == "$before" ]] || fail $'hold/lock state changed.\nbefore:\n'"$before"$'\nafter:\n'"$after"
|
|
if [[ $BE == apt ]]; then [[ ! -e $STATE_DIR/holds.added ]]; fi
|
|
}
|
|
|
|
@test "trusting a package re-includes its excluded dependency" {
|
|
run skeptical-updater <<<$'2-\n1+\n'
|
|
assert_success
|
|
assert_line ' (su-dummy-b is trusted now: no longer excluded from this run)'
|
|
assert_line 'Excluded from this run: none'
|
|
[[ $(versions) == "a=2.0 b=2.0 c=2.0" ]] || fail "versions after the run: $(versions)"
|
|
}
|
|
|
|
@test "enter upgrades everything" {
|
|
run skeptical-updater <<<''
|
|
assert_success
|
|
assert_line 'Excluded from this run: none'
|
|
[[ $(versions) == "a=2.0 b=2.0 c=2.0" ]] || fail "versions after the run: $(versions)"
|
|
run skeptical-updater list --no-refresh
|
|
assert_success
|
|
assert_output --partial 'Nothing to upgrade.'
|
|
}
|
|
|
|
@test "Nx purges su-dummy-c after a y confirmation" {
|
|
run skeptical-updater --no-refresh <<<$'3x\ny\nl\nq'
|
|
assert_success
|
|
assert_line 'Purge su-dummy-c now? [y/N] y'
|
|
assert_line 'purged: su-dummy-c'
|
|
assert_line '2 upgradable, 0 trusted (hidden, use --all to show), 2 to review:'
|
|
[[ $(versions) == "a=1.0 b=1.0 c=absent" ]] || fail "versions after the run: $(versions)"
|
|
[[ $(pkg_ver su-dummy-orphan) == 1.0 ]] || fail "the unrelated orphan was removed"
|
|
}
|
|
|
|
@test "Nx on su-dummy-b is refused: su-dummy-a depends on it; both stay, the row stays listed" {
|
|
run skeptical-updater --no-refresh <<<$'2x\nl\nq'
|
|
assert_success
|
|
assert_line 'not purged: su-dummy-b is required by: su-dummy-a - purge the dependents first'
|
|
refute_output --partial '[y/N]'
|
|
[[ $(grep -c '^ \[2\] su-dummy-b ' <<<"$output") -eq 2 ]] || fail "row 2 left the list"
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]] || fail "versions after the run: $(versions)"
|
|
}
|
|
|
|
@test "Nx on su-dummy-a removes su-dummy-b with it (its dependency, nothing else needs it); the orphan survives" {
|
|
run skeptical-updater --no-refresh <<<$'1x\ny\nl\nq'
|
|
assert_success
|
|
assert_line 'Purge su-dummy-a now? This also removes: su-dummy-b [y/N] y'
|
|
assert_line 'purged: su-dummy-a su-dummy-b'
|
|
assert_line '1 upgradable, 0 trusted (hidden, use --all to show), 1 to review:'
|
|
[[ $(versions) == "a=absent b=absent c=1.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ $(pkg_ver su-dummy-orphan) == 1.0 ]] || fail "the unrelated orphan was removed"
|
|
}
|
|
|
|
@test "purging every package ends the session cleanly" {
|
|
run skeptical-updater --no-refresh <<<$'1x\ny\n3x\ny'
|
|
assert_success
|
|
assert_line 'Nothing left to upgrade.'
|
|
[[ $(versions) == "a=absent b=absent c=absent" ]] || fail "versions after the run: $(versions)"
|
|
[[ $(pkg_ver su-dummy-orphan) == 1.0 ]] || fail "the unrelated orphan was removed"
|
|
}
|
|
|
|
@test "Nx answered with anything but y keeps the package" {
|
|
run skeptical-updater --no-refresh <<<$'3x\nn\nq'
|
|
assert_success
|
|
assert_line 'not purged: su-dummy-c'
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
}
|
|
|
|
@test "q leaves everything untouched" {
|
|
before=$(holds_snapshot)
|
|
run skeptical-updater <<<$'2-\n1-\nq'
|
|
assert_success
|
|
assert_line 'Quit: nothing was upgraded.'
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
[[ $(holds_snapshot) == "$before" ]]
|
|
[[ ! -e $STATE_FILE ]]
|
|
}
|
|
|
|
@test "EOF aborts with exit 2 and changes nothing" {
|
|
before=$(holds_snapshot)
|
|
run skeptical-updater <<<'2-'
|
|
assert_failure 2
|
|
assert_output --partial 'end of input: aborted, nothing was upgraded'
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
[[ $(holds_snapshot) == "$before" ]]
|
|
[[ ! -e $STATE_FILE ]]
|
|
}
|
|
|
|
@test "on a terminal, Up recalls the previous line (readline, history of this session only)" {
|
|
pty_session $'1?\r\e[A\rq\r' --no-refresh
|
|
assert_success
|
|
[[ $(grep -c '^su-dummy-a: ' <<<"$output") -eq 2 ]] || fail "1? should have run twice (Up + Enter)"
|
|
assert_line 'Quit: nothing was upgraded.'
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
}
|
|
|
|
@test "--dry-run: enter prints the native upgrade command and changes nothing" {
|
|
before=$(holds_snapshot)
|
|
run skeptical-updater --dry-run <<<''
|
|
assert_success
|
|
assert_line --regexp "$(native_upgrade_regex)"
|
|
assert_line 'Dry run: nothing was changed.'
|
|
# (3+: trusting su-dummy-a would hide su-dummy-b and so re-include it)
|
|
run skeptical-updater --dry-run <<<$'2-\n3+\n'
|
|
assert_success
|
|
case $BE in
|
|
apt)
|
|
assert_line '+ apt-mark hold su-dummy-b'
|
|
assert_line '+ apt-mark unhold su-dummy-b'
|
|
;;
|
|
pacman)
|
|
assert_line --regexp '^\+ cp -p -- /tmp/skeptical-updater-db\.[0-9]+\.[A-Za-z0-9]+/sync/su-dummy\.db /var/lib/pacman/sync/$'
|
|
assert_line '+ pacman -Su --noconfirm --ignore su-dummy-b'
|
|
;;
|
|
dnf) assert_line --regexp '^\+ (dnf|yum) -y --setopt=skip_if_unavailable=0 --setopt=\\\*\.metadata_expire=-1 upgrade --exclude=su-dummy-b$' ;;
|
|
zypper)
|
|
assert_line --regexp '^\+ env ZYPP_CONF=.*/zypp\.conf zypper --non-interactive --quiet addlock su-dummy-b$'
|
|
assert_line --regexp "^\+ env ZYPP_CONF=.*/zypp\.conf zypper --non-interactive --no-refresh $(zypper_verb)\$"
|
|
;;
|
|
esac
|
|
assert_line --partial "+ $STATE_FILE add: $BE su-dummy-c user"
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
[[ $(holds_snapshot) == "$before" ]]
|
|
[[ ! -e $STATE_DIR ]]
|
|
}
|
|
|
|
@test "read-only commands work unprivileged" {
|
|
if command -v setpriv >/dev/null 2>&1; then
|
|
asuser() { setpriv --reuid=65534 --regid=65534 --clear-groups -- env TMPDIR=/tmp "$@"; }
|
|
elif command -v python3 >/dev/null 2>&1; then # almalinux:10 has neither setpriv nor runuser/su
|
|
asuser() { python3 -c 'import os, sys; os.setgroups([]); os.setgid(65534); os.setuid(65534); os.execvp(sys.argv[1], sys.argv[1:])' env TMPDIR=/tmp "$@"; }
|
|
else
|
|
skip "neither setpriv nor python3 available to drop privileges"
|
|
fi
|
|
skeptical-updater trust su-dummy-c >/dev/null
|
|
run asuser skeptical-updater trusted
|
|
assert_success
|
|
assert_line --partial "$BE"$'\t'"su-dummy-c"$'\t'"user"
|
|
run asuser skeptical-updater info su-dummy-b
|
|
assert_success
|
|
assert_line 'reason: installed as a dependency'
|
|
assert_line 'required by: su-dummy-a'
|
|
run asuser skeptical-updater info su-dummy-a
|
|
assert_success
|
|
assert_line 'reason: explicitly installed'
|
|
run asuser skeptical-updater --dry-run --no-refresh <<<''
|
|
assert_success
|
|
assert_line --regexp "$(native_upgrade_regex)"
|
|
run asuser skeptical-updater upgrade-me-please
|
|
assert_failure 1
|
|
# a real upgrade without root and without sudo is refused
|
|
if ! command -v sudo >/dev/null 2>&1; then
|
|
run asuser skeptical-updater <<<''
|
|
assert_failure 1
|
|
assert_output --partial 'upgrading needs root and sudo is not available'
|
|
fi
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]]
|
|
# a state directory an unprivileged user cannot enter is an error, not "no trusted packages"
|
|
chmod 0000 /var/lib/skeptical-updater
|
|
run asuser skeptical-updater trusted
|
|
chmod 0755 /var/lib/skeptical-updater
|
|
assert_failure 1
|
|
assert_output --partial 'cannot access the state directory /var/lib/skeptical-updater (permission denied)'
|
|
}
|
|
|
|
@test "pacman: list, q, end of input and --dry-run never touch the real sync database" {
|
|
[[ $BE == pacman ]] || skip "pacman only"
|
|
before=$(pacman_sync_snapshot)
|
|
run skeptical-updater list
|
|
assert_success
|
|
run skeptical-updater <<<'q'
|
|
assert_success
|
|
run skeptical-updater <<<'2-'
|
|
assert_failure 2
|
|
run skeptical-updater --dry-run <<<''
|
|
assert_success
|
|
assert_line 'Checking the reviewed transaction (pacman -Sup)... ok.'
|
|
assert_line '+ pacman -Su --noconfirm'
|
|
after=$(pacman_sync_snapshot)
|
|
[[ $after == "$before" ]] || fail $'the real sync database changed.\nbefore:\n'"$before"$'\nafter:\n'"$after"
|
|
run ls /tmp
|
|
refute_output --partial 'skeptical-updater-db.'
|
|
}
|
|
|
|
@test "apt: temporary holds wait for a busy dpkg lock instead of failing" {
|
|
[[ $BE == apt ]] || skip "apt only"
|
|
command -v perl >/dev/null 2>&1 || skip "perl not available"
|
|
# hold dpkg's frontend lock for 4 s (fcntl, as dpkg does), starting now
|
|
perl -e 'use Fcntl; open(my $f, ">>", "/var/lib/dpkg/lock-frontend") or die; my $l = pack("s s l l i", F_WRLCK, 0, 0, 0, 0); fcntl($f, F_SETLKW, $l) or die; sleep 4;' &
|
|
locker=$!
|
|
sleep 0.5
|
|
run skeptical-updater --no-refresh <<<$'2-\n'
|
|
wait "$locker" || true
|
|
assert_success
|
|
assert_line 'Excluded from this run: su-dummy-b'
|
|
[[ $(versions) == "a=2.0 b=1.0 c=2.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ -z $(apt-mark showhold) ]]
|
|
}
|
|
|
|
@test "zypper: a lock whose locksfile.path comes from a zypp.conf.d drop-in is honoured" {
|
|
[[ $BE == zypper ]] || skip "zypper only"
|
|
mkdir -p /etc/zypp/zypp.conf.d
|
|
printf '[main]\nlocksfile.path = /etc/zypp/locks-su-e2e\n' >/etc/zypp/zypp.conf.d/50-su-e2e.conf
|
|
zypper --non-interactive --quiet addlock su-dummy-c >/dev/null
|
|
grep -q 'solvable_name: su-dummy-c' /etc/zypp/locks-su-e2e
|
|
before=$(cat /etc/zypp/locks-su-e2e)
|
|
run skeptical-updater <<<$'2-\n'
|
|
assert_success
|
|
assert_line 'Excluded from this run: su-dummy-b'
|
|
[[ $(versions) == "a=2.0 b=1.0 c=1.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ $(cat /etc/zypp/locks-su-e2e) == "$before" ]]
|
|
}
|
|
|
|
@test "zypper: the reviewed metadata is applied (no refresh between review and upgrade)" {
|
|
[[ $BE == zypper ]] || skip "zypper only (libdnf reads file:// repositories live; apt never refreshes on upgrade)"
|
|
mkfifo "$BATS_TEST_TMPDIR/in"
|
|
skeptical-updater <"$BATS_TEST_TMPDIR/in" >"$BATS_TEST_TMPDIR/out" 2>&1 &
|
|
pid=$!
|
|
exec {w}>"$BATS_TEST_TMPDIR/in" # (fd 3 belongs to bats)
|
|
for _ in $(seq 1 600); do
|
|
grep -q '^<enter> upgrade' "$BATS_TEST_TMPDIR/out" && break
|
|
sleep 0.1
|
|
done
|
|
# a newer su-dummy-c appears in the repository after the review
|
|
rpm_publish su-dummy-c 3.0
|
|
echo >&"$w"
|
|
exec {w}>&-
|
|
rc=0
|
|
wait "$pid" || rc=$?
|
|
rpm_unpublish su-dummy-c 3.0
|
|
[[ $rc -eq 0 ]] || fail "exit $rc: $(cat "$BATS_TEST_TMPDIR/out")"
|
|
[[ $(versions) == "a=2.0 b=2.0 c=2.0" ]] || fail "versions after the run: $(versions)"
|
|
}
|
|
|
|
@test "pacman: package databases synced elsewhere during the review: refused (exit 2), nothing changed" {
|
|
[[ $BE == pacman ]] || skip "pacman only"
|
|
session_start
|
|
sleep 1
|
|
pacman_publish su-dummy-c 3.0
|
|
pacman -Sy >/dev/null 2>&1 # another terminal: the system's database is now newer than the reviewed one
|
|
synced=$(sha256sum /var/lib/pacman/sync/su-dummy.db | cut -d' ' -f1)
|
|
session_finish ''
|
|
pacman_unpublish
|
|
pacman -Sy >/dev/null 2>&1
|
|
[[ $SESSION_RC -eq 2 ]] || fail "exit $SESSION_RC: $(cat "$BATS_TEST_TMPDIR/out")"
|
|
grep -q 'package databases changed since the review (su-dummy); run skeptical-updater again' "$BATS_TEST_TMPDIR/out"
|
|
[[ $(versions) == "a=1.0 b=1.0 c=1.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ ! -e /var/lib/pacman/db.lck ]]
|
|
[[ -n $synced ]]
|
|
}
|
|
|
|
@test "pacman: <enter> installs exactly the reviewed metadata (the real sync DB becomes the reviewed one)" {
|
|
[[ $BE == pacman ]] || skip "pacman only"
|
|
# the system's database is older than what the review will see (su-dummy-c 3.0) ...
|
|
# (1 s apart from the previous repo rebuild: pacman compares database mtimes in seconds)
|
|
sleep 1
|
|
pacman_publish su-dummy-c 3.0
|
|
session_start
|
|
reviewed=$(sha256sum /tmp/skeptical-updater-db."$SESSION_PID".*/sync/su-dummy.db | cut -d' ' -f1)
|
|
# ... and su-dummy-c 4.0 appears in the repository after the review
|
|
sleep 1
|
|
pacman_publish su-dummy-c 4.0
|
|
session_finish ''
|
|
pacman_unpublish
|
|
[[ $SESSION_RC -eq 0 ]] || fail "exit $SESSION_RC: $(cat "$BATS_TEST_TMPDIR/out")"
|
|
grep -qE '^\+ cp -p -- /tmp/skeptical-updater-db\.[0-9]+\.[A-Za-z0-9]+/sync/su-dummy\.db /var/lib/pacman/sync/$' "$BATS_TEST_TMPDIR/out"
|
|
[[ -n $reviewed ]]
|
|
[[ $(sha256sum /var/lib/pacman/sync/su-dummy.db | cut -d' ' -f1) == "$reviewed" ]] || fail "the system's su-dummy.db is not the reviewed one"
|
|
[[ $(versions) == "a=2.0 b=2.0 c=3.0" ]] || fail "versions after the run: $(versions)"
|
|
[[ ! -e /var/lib/pacman/db.lck ]]
|
|
run ls /tmp
|
|
refute_output --partial 'skeptical-updater-db.'
|
|
}
|