1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
summary: Ensure that the audio-playback/record interface works
details: |
Historically snapd offered the pulseaudio interface which allowed both
playback and recording capabilities. Over time those were split into the
audio-playback and audio-record interfaces, that grant the same permission
to interact with pulseaudio APIs, but rely on an additional patch present in
Ubuntu, which checks for the interface connection before allowing recording
to take place.
The patch is in debian/patches/0700-modules-add-snappy-policy-module.patch
in the source package of pulseaudio in the Ubuntu archive.
The test exercises that both audio playback and recording are really governed
by the interface connection.
# Only classic Ubuntu has the pulseaudio mediation patches. Ubuntu 14.04 is unsupported on the desktop.
# TODO: extend tests.session and run this test on 14.04 as well.
systems: [ubuntu-16.04-*, ubuntu-18.04-*, ubuntu-2*]
environment:
PLAY_FILE: "/snap/test-snapd-audio-record/current/usr/share/sounds/alsa/Noise.wav"
# today, 16.04 and higher have a mediating pulseaudio
EXFAIL: "ubuntu-14"
prepare: |
# Install pulseaudio.
apt update
apt install -y pulseaudio pulseaudio-utils
# Remove the package and reload systemd later, when we are restoring. This
# is important because of rtkit-daemon.service that gets pulled by
# pulseaudio and that is subsequently removed.
tests.cleanup defer systemctl daemon-reload
tests.cleanup defer apt-get autoremove --purge -y pulseaudio pulseaudio-utils
# Make sure the socket and the server is available in the user session.
if [ "$(systemctl --user --global is-enabled pulseaudio.socket)" != enabled ]; then
systemctl --user --global enable pulseaudio.socket
tests.cleanup defer systemctl --user --global disable pulseaudio.socket
fi
if [ "$(systemctl --user --global is-enabled pulseaudio.service)" != enabled ]; then
systemctl --user --global enable pulseaudio.service
tests.cleanup defer systemctl --user --global disable pulseaudio.service
fi
# Install a snap that uses the audio-playback/audio-record interfaces.
snap install --edge test-snapd-audio-record
tests.cleanup defer snap remove --purge test-snapd-audio-record
# TODO: move this to the test that is responsible for creating this data.
# Remove potentially large go build cache that makes the debug section more
# verbose.
rm -rf ~test/.cache/go-build
# TODO: fix the test causing this. Some test is making ~test/.config root-owned,
# making it impossible for pulseaudio to start and write the secure cookie file.
chown -R test ~test
# Prepare a session for the user.
tests.session -u test prepare
tests.cleanup defer tests.session -u test restore
# Ensure that the socket is active but do not check the service. In user
# mode pulseaudio is documented to quit when there are no active logind
# sessions.
#
# User session services do not posses a logind session session so
# pulseaudio immediately quits, and remains inactive outside of the moments
# we execute paplay through tests.session.
tests.session -u test exec systemctl --user is-active pulseaudio.socket | MATCH active
# Start pulseaudio to give it a chance to write the pulseaudio cookie file.
# Otherwise paplay invocation will race with pulse startup, and will race
# with cookie file being available.
if not tests.session -u test exec systemctl --user start pulseaudio.service; then
echo "cannot start pulseaudio server"
tests.session -u test exec systemctl --user status pulseaudio.service || true
tests.session -u test exec journalctl --user -u pulseaudio.service || true
exit 1
fi
# Ensure, that the cookie file is present.
test -e ~test/.config/pulse/cookie || test -e ~test/.config/pulse/.pulse-cookie
tests.cleanup defer rm -rf ~test/.config/pulse
# enable debug logging in pulseaudio
cp /etc/pulse/daemon.conf /etc/pulse/daemon.conf.backup
echo 'log-level = debug' >> /etc/pulse/daemon.conf
tests.cleanup defer mv /etc/pulse/daemon.conf.backup /etc/pulse/daemon.conf
# disable start limit checking for pulseaudio service
mkdir -p /etc/systemd/user/pulseaudio.service.d
cat <<-EOF > /etc/systemd/user/pulseaudio.service.d/no-start-limit.conf
[Unit]
StartLimitBurst=0
EOF
tests.cleanup defer rm /etc/systemd/user/pulseaudio.service.d/no-start-limit.conf
# reload user's systemd instance
tests.session -u test exec systemctl daemon-reload --user
debug: |
echo "Files present in the test user's home directory"
test -d /home/test && find /home/test
echo "Files present in the test user's home directory, that are owned by root"
test -d /home/test && find /home/test -user root
echo "Files present in the test user's runtime directory"
test -d /home/user/12345 && find /run/user/12345
echo "Processes running as the test user"
ps -u test
echo "Pulseaudio log"
tests.session -u test exec journalctl --user -u pulseaudio.service || true
execute: |
echo "The unconfined user can play audio"
tests.session -u test exec /usr/bin/paplay "$PLAY_FILE"
echo "The unconfined user can record audio"
tests.session -u test exec /snap/test-snapd-audio-record/current/bin/parec-simple
echo "The audio-playback interface is connected by default"
snap connections test-snapd-audio-record | MATCH "audio-playback +test-snapd-audio-record:audio-playback +:audio-playback +-"
echo "The audio-record interface is disconnected by default"
snap connections test-snapd-audio-record | MATCH "audio-record +test-snapd-audio-record:audio-record +- +-"
echo "When the audio-playback plug is connected"
snap connect test-snapd-audio-record:audio-playback
echo "Then the snap can play audio"
tests.session -u test exec test-snapd-audio-record.play "$PLAY_FILE"
echo "When the audio-record plug is connected"
snap connect test-snapd-audio-record:audio-record
echo "Then the snap can record audio"
tests.session -u test exec test-snapd-audio-record.recsimple
echo "When the audio-record plug is disconnected"
snap disconnect test-snapd-audio-record:audio-record
mediating_pa="yes"
if echo "$SPREAD_SYSTEM" | grep -Eq "$EXFAIL" ; then
mediating_pa="no"
fi
echo "Then the snap command is not able to record audio"
if [ "$mediating_pa" = "no" ] && ! tests.session -u test exec test-snapd-audio-record.recsimple; then
echo "Could not record audio. Does '$SPREAD_SYSTEM' have mediation patches?"
exit 1
elif [ "$mediating_pa" = "yes" ] && tests.session -u test exec test-snapd-audio-record.recsimple; then
echo "Could record audio even though '$SPREAD_SYSTEM' should have mediation patches"
exit 1
fi
if [ "$(snap debug confinement)" = "partial" ] ; then
exit 0
fi
echo "When the audio-playback plug is disconnected"
snap disconnect test-snapd-audio-record:audio-playback
echo "Then the snap command is not able to connect to the pulseaudio socket"
if tests.session -u test exec test-snapd-audio-record.play "$PLAY_FILE"; then
echo "Expected error with plug disconnected"
exit 1
fi
|