wren-linux / tools / test-user-audio.sh
#!/bin/bash
# Checks that your own sound server (PipeWire) starts at login only with the sound
# extra (user_audio_sync in lib/core.sh): the sandboxed browsers install PipeWire's
# programs for a sound server of their own, and Debian then starts it for every user.
# With a pretend systemctl, sudo and unit folder; changes nothing outside a temp folder.
# Run by test.sh, or: bash tools/test-user-audio.sh
# shellcheck disable=SC2016 # the inner bash expands its own variables
HERE=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
T=$(mktemp -d) || { echo " FAIL couldn't make a temp folder (is /tmp full?)"; exit 1; }
trap 'rm -rf "$T"' EXIT
mkdir -p "$T/fake" "$T/units"
# this Debian's units: all but filter-chain, to see that a missing one isn't named
for u in pipewire.socket pipewire.service pipewire-pulse.socket pipewire-pulse.service wireplumber.service; do : >"$T/units/$u"; done
printf '#!/bin/sh\necho "systemctl $*" >>"%s/calls"\n' "$T" >"$T/fake/systemctl"
printf '#!/bin/sh\necho "sudo $*" >>"%s/calls"\nexec "$@"\n' "$T" >"$T/fake/sudo"
chmod +x "$T/fake/"*
export WREN_USER_UNIT_DIR=$T/units WREN_SUDO=$T/fake/sudo
# shellcheck disable=SC1091
. "$HERE/lib.sh"
set +e +o pipefail
fails=0
check() { # DESCRIPTION CONDITION-COMMAND...
local what=$1
shift
if "$@" >/dev/null 2>&1; then printf ' ok %s\n' "$what"; else printf ' FAIL %s\n' "$what"; fails=$((fails + 1)); fi
}
not() { ! "$@"; }
# sync EXTRA-INSTALLED(yes|no): user_audio_sync with that answer, its calls in $T/calls
sync() (
: >"$T/calls"
if [ "$1" = yes ]; then is_installed() { [ "$1" = pipewire-audio ]; }; else is_installed() { return 1; }; fi
PATH="$T/fake:$PATH" user_audio_sync
)
sync no
check "without the sound extra: Debian's start for every user is switched off" \
grep -qx "systemctl --global disable pipewire.socket pipewire.service pipewire-pulse.socket pipewire-pulse.service wireplumber.service" "$T/calls"
check "...through sudo" grep -q "^sudo systemctl --global disable" "$T/calls"
check "...and yours stops now" \
grep -qx "systemctl --user disable --now pipewire.socket pipewire.service pipewire-pulse.socket pipewire-pulse.service wireplumber.service" "$T/calls"
check "...naming only the units this Debian has (systemctl stops at one it doesn't know)" not grep -q filter-chain "$T/calls"
check "...and nothing is switched on" not grep -q " enable" "$T/calls"
sync yes
check "with the sound extra: on for every user" grep -qx "systemctl --global enable pipewire.socket pipewire-pulse.socket wireplumber.service" "$T/calls"
check "...and nothing switched off" not grep -q "disable" "$T/calls"
rm -f "$T/units/"*
sync no
check "no PipeWire on this computer: nothing is asked of systemctl" test ! -s "$T/calls"
# Who calls it, and where: after installing PipeWire's programs, before anything else
order() { # FILE TEXT-BEFORE TEXT-AFTER: the second comes somewhere after the first
python3 -I -c 'import sys; s = open(sys.argv[1]).read(); assert sys.argv[3] in s[s.index(sys.argv[2]):]' "$@"
}
# apt_install itself: whichever script installs PipeWire's packages (the sandboxed browsers,
# incognito, Firefox, Tor Browser, Mullvad Browser), yours is switched off after, every time
# (Tor Browser's and Mullvad Browser's didn't: the ultra review found it)
ai() ( # PACKAGES...: apt_install with the install itself and user_audio_sync pretending
_apt_install() { echo "installed $*"; }
user_audio_sync() { echo synced; }
apt_install "$@"
)
check "installing PipeWire's packages, whoever asks: then yours is switched off (user_audio_sync)" \
test "$(ai cage pipewire-bin wireplumber | paste -sd,)" = "installed cage pipewire-bin wireplumber,synced"
check "...also a rerun with nothing new to install" bash -c '[ "$(grep -c synced <<<"$1")" = 1 ]' _ "$(ai pipewire-pulse)"
check "...and not for anything else" test "$(ai cage nftables)" = "installed cage nftables"
for x in parts/incognito.sh extras/firefox-sandbox.sh extras/tor-browser.sh extras/mullvad-browser-sandbox.sh; do
check "$x installs PipeWire's packages through apt_install (so they're followed by the switch)" \
bash -c 'tr "\n" " " <"$1" | sed "s/\\\\ */ /g" | grep -qE "apt_install [^;]*pipewire-bin pipewire-pulse wireplumber"' _ "$HERE/$x"
done
check "the sound extra switches it on again after installing" order "$HERE/extras/pipewire-audio.sh" 'apt_install pipewire-audio' 'user_audio_sync'
check "...and off when it is removed (the sandboxes keep the programs)" \
bash -c 'sed -n "/--remove/,/^fi/p" "$1" | grep -q user_audio_sync' _ "$HERE/extras/pipewire-audio.sh"
check "without the sound extra Firefox doesn't ask about sound: it has none" \
order "$HERE/extras/firefox-sandbox.sh" 'if ! user_audio_wanted; then' 'ask "Sound in Firefox'
check "...and incognito says so instead of promising sound" \
bash -c 'grep -q "No sound: that needs the sound extra" "$1" && grep -B2 "Videos play with sound" "$1" | grep -q user_audio_wanted' _ "$HERE/parts/incognito.sh"
check "the manual steps say it too" bash -c 'grep -q "systemctl --global disable pipewire.socket" "$1" && grep -q "systemctl --global enable pipewire.socket" "$2"' _ \
"$HERE/docs/extras/firefox-sandbox.md" "$HERE/docs/extras/pipewire-audio.md"
[ "$fails" -eq 0 ]