# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import glob import os import re import stat import subprocess from autotest_lib.client.common_lib import error from autotest_lib.client.bin import test from autotest_lib.client.bin import utils _SND_DEV_DIR = '/dev/snd/' _SND_DEFAULT_MASK = 'controlC*' class sound_infrastructure(test.test): """ Tests that the expected sound infrastructure is present. Check that at least one playback and capture device exists and that their permissions are configured properly. """ version = 2 _NO_PLAYBACK_BOARDS_LIST = [] _NO_RECORDER_BOARDS_LIST = ['veyron_mickey'] _NO_AUDIO_DEVICE_LIST = ['veyron_rialto'] def check_snd_dev_perms(self, filename): desired_mode = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IFCHR) st = os.stat(filename) if (st.st_mode != desired_mode): raise error.TestFail("Incorrect permissions for %s" % filename) def check_sound_files(self, playback=True, record=True): """Checks sound files present in snd directory. @param playback: Checks playback device. @param record: Checks record device. @raises: error.TestFail if sound file is missing. """ patterns = {'^controlC(\d+)': False} if playback: patterns['^pcmC(\d+)D(\d+)p$'] = False if record: patterns['^pcmC(\d+)D(\d+)c$'] = False filenames = os.listdir(_SND_DEV_DIR) for filename in filenames: for pattern in patterns: if re.match(pattern, filename): patterns[pattern] = True self.check_snd_dev_perms(_SND_DEV_DIR + filename) for pattern in patterns: if not patterns[pattern]: raise error.TestFail("Missing device %s" % pattern) def check_device_list(self, playback=True, record=True): """Checks sound card and device list by alsa utils command. @param playback: Checks playback sound card and devices. @param record: Checks record sound card and devices. @raises: error.TestFail if no playback/record devices found. """ no_cards_pattern = '.*no soundcards found.*' if playback: aplay = subprocess.Popen(["aplay", "-l"], stderr=subprocess.PIPE) aplay_list = aplay.communicate()[1] if aplay.returncode or re.match(no_cards_pattern, aplay_list): raise error.TestFail("No playback devices found by aplay") if record: no_cards_pattern = '.*no soundcards found.*' arecord = subprocess.Popen( ["arecord", "-l"], stderr=subprocess.PIPE) arecord_list = arecord.communicate()[1] if arecord.returncode or re.match(no_cards_pattern, arecord_list): raise error.TestFail("No record devices found by arecord") def run_once(self): board = utils.get_board().lower() snd_control = len(glob.glob(_SND_DEV_DIR + _SND_DEFAULT_MASK)) if board in self._NO_AUDIO_DEVICE_LIST: if snd_control: raise error.TestError('%s is not supposed to have sound control!' % board) else: return record = board not in self._NO_RECORDER_BOARDS_LIST playback = board not in self._NO_PLAYBACK_BOARDS_LIST self.check_sound_files(playback, record) self.check_device_list(playback, record)