Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkbox 691/missing audio device (New) #622

Merged
merged 23 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions providers/base/bin/alsa_pcm_info.py

This file was deleted.

26 changes: 13 additions & 13 deletions providers/base/units/audio/jobs.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -699,12 +699,12 @@ imports: from com.canonical.plainbox import manifest
requires:
manifest.has_audio_playback == 'True'
command:
COUNT=$(alsa_pcm_info.py | grep -c Playback)
echo "Count: $COUNT"
if [ "$COUNT" -eq 0 ]; then
exit 1
fi
estimated_duration: 1s
COUNT=$(audio_card_resource.py | grep -c 'playback: supported')
echo "Count: $COUNT"
if [ "$COUNT" -eq 0 ]; then
exit 1
fi
estimated_duration: 0.5

id: audio/detect-capture-devices
_summary: Check that at least one audio capture device exists
Expand All @@ -715,12 +715,12 @@ imports: from com.canonical.plainbox import manifest
requires:
manifest.has_audio_capture == 'True'
command:
COUNT=$(alsa_pcm_info.py | grep -c Capture)
echo "Count: $COUNT"
if [ "$COUNT" -eq 0 ]; then
exit 1
fi
esimated_duration: 1s
COUNT=$(audio_card_resource.py | grep -c 'capture: supported')
echo "Count: $COUNT"
if [ "$COUNT" -eq 0 ]; then
exit 1
fi
esimated_duration: 0.5

id: audio/alsa-playback
_summary: Playback works
Expand Down Expand Up @@ -920,4 +920,4 @@ plugin: manual
flags: also-after-suspend
requires: snap.name == 'pulseaudio'
category_id: com.canonical.plainbox::audio
estimated_duration: 1m
estimated_duration: 1m
9 changes: 0 additions & 9 deletions providers/base/units/audio/resource.pxu

This file was deleted.

2 changes: 1 addition & 1 deletion providers/base/units/audio/test-plan.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,4 @@ _description: Automated audio tests for Snappy Ubuntu Core devices
include:
after-suspend-audio/detect-playback-devices
after-suspend-audio/detect-capture-devices
after-suspend-audio/alsa-loopback-automated
after-suspend-audio/alsa-loopback-automated
82 changes: 82 additions & 0 deletions providers/resource/bin/audio_card_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
#
# This file is part of Checkbox.
#
# Copyright 2023 Canonical Ltd.
# Authors: Dio He <dio.he@canonical.com>
#
# Checkbox is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3,
# as published by the Free Software Foundation.
#
# Checkbox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.


def get_audio_cards():
"""Retrieve audio card information."""
audio_cards = []
PCM_FILE = '/proc/asound/pcm'
try:
with open(PCM_FILE, 'r') as f:
data = f.readlines()
except OSError:
print('Failed to access {}'.format(PCM_FILE))
return []

for line in data:
info = [device_line.strip() for device_line in line.split(':')]
ids = info[0].split('-')
card_id = ids[0]
device_id = ids[1]
device_name = info[1]
capabilities = info[3:]
playback = has_capability('playback', capabilities)
capture = has_capability('capture', capabilities)
audio_cards.append({
'card': card_id,
'device': device_id,
'name': device_name,
'playback': playback,
'capture': capture
})

return audio_cards


def has_capability(capability_prefix: str, capabilities: list) -> bool:
return any(capability.startswith(capability_prefix)
for capability in capabilities)


def print_audio_cards(cards):
"""Print audio card information."""
for card in cards:
print("card: {}".format(card["card"]))
print("device: {}".format(card["device"]))
print("name: {}".format(card["name"]))
if card["playback"]:
print("playback: supported")
else:
print("playback: unsupported")
if card["capture"]:
print("capture: supported")
else:
print("capture: unsupported")
print()


def main():
cards = get_audio_cards()

if cards:
print_audio_cards(cards)


if __name__ == "__main__":
main()
8 changes: 8 additions & 0 deletions providers/resource/jobs/resource.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,11 @@ command:
else
echo "detected: false"
fi

id: audio_card
estimated_duration: 0.05
plugin: resource
_summary: Collect information about the audio card
_description: Gets audio resource info from /proc/asound/pcm
command: audio_card_resource.py

37 changes: 37 additions & 0 deletions providers/resource/tests/test_audio_card_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
diohe0311 marked this conversation as resolved.
Show resolved Hide resolved
#
# This file is part of Checkbox.
#
# Copyright 2023 Canonical Ltd.
# Authors: Dio He <dio.he@canonical.com>
#
# Checkbox is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3,
# as published by the Free Software Foundation.
#
# Checkbox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.

import unittest
from io import StringIO
from unittest.mock import Mock, patch, mock_open
from audio_card_resource import get_audio_cards


class GetAudioCardsTests(unittest.TestCase):
def test_get_audio_card_info(self):
with patch("os.path.exists") as mock_path:
mock_path.return_value = True
test_input = "00-00: HDA Analog (*) : : playback 1\n00-01: HDA Digital (*) : : capture 1s"
expected_audio_card1 = {'card': '00', 'device': '00', 'name': 'HDA Analog (*)', 'playback': True, 'capture': False}
expected_audio_card2 = {'card': '00', 'device': '01', 'name': 'HDA Digital (*)', 'playback': False, 'capture': True}
with patch("builtins.open", new=mock_open(read_data=test_input)):
audio_cards = get_audio_cards()
self.assertEqual(audio_cards[0], expected_audio_card1)
self.assertEqual(audio_cards[1], expected_audio_card2)

Loading