blob: a88a50ece96515f17f1112df3a2c9948d9ef086f [file] [log] [blame]
# 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.
from autotest_lib.client.common_lib import error
from autotest_lib.client.bin import test, utils
import logging
import os
import re
class sound_infrastructure(test.test):
"""
Tests that the expected sound infrastructure is present.
If a file is found to be missing, that would imply that the driver
has changed, and this will have an impact on the entire sound
system.
Before submitting the fixes, test & verify:
o Sound controls still work on each affected target device
Volume Up, Volume Down, Mute
Any UI for controlling AV output
o I/O devices continue to work
Headphone,
Internal Speakers
HDMI
Internal Mic
o To create 'files' data file:
Execute the following on the DUT:
tar --absolute-names -c /dev/snd /proc/asound 2>/dev/null| \
tar -t 2>/dev/null|sed -e 's./$..g' >{codec-name}.files
{codec-name} should be replaced with the name of the codec.
Replace spaces in the codec name with '_'.
See get_codec() to help determine the name of the codec.
"""
version = 1
codec_info = {
'ALL': { # Things common to all sound codecs
'files': [
'/etc/init/cras.conf', # Upstart script, from ADHD package
'/etc/asound.state', # Factory defaults. From ADHD.
'/usr/bin/alsamixer',
'/usr/bin/amixer',
'/usr/sbin/alsactl',
'/usr/share/alsa/init/00main',
'/usr/share/alsa/init/default',
'/usr/share/alsa/init/hda',
'/usr/share/alsa/init/help',
'/usr/share/alsa/init/info',
'/usr/share/alsa/init/test',
]
},
'WM8903': {
'files' : [ ],
},
'ALC271X': {
'files' : [ ],
},
'Cirrus Analog': {
'files' : [ ],
},
'ALC269VB': {
'files' : [ ],
},
'ALC272': {
'files' : [ ],
}
}
# These are the card index patterns that may appear in the
# filenames. We will replace the card index with the actual value
# before matching the filename. For example, if the actual card
# index is 1, we will change "/dev/snd/controlC0" into
# "/dev/snd/controlC1" before matching.
card_patterns = [
"^/dev/snd/controlC(\d+)",
"^/dev/snd/hwC(\d+)",
"^/dev/snd/pcmC(\d+)",
"^/proc/asound/card(\d+)",
]
def replace_card_index(self, input):
for p in self.card_patterns:
m = re.match(p, input)
if m is None: continue
start, end = m.span(1)
return input[:start] + str(self.card_index) + input[end:]
return input
# Finds a card with the given codec name. Returns (found, card_index)
def find_card(self, codec):
r = utils.run("aplay -l|grep -e '%s'" % (codec), ignore_status = True,
stdout_tee = utils.TEE_TO_LOGS,
stderr_tee = utils.TEE_TO_LOGS)
if r.exit_status != 0:
return False, 0
m = re.match("card (\d+):", r.stdout)
if m is None:
return False, 0
return True, int(m.group(1))
def exec_cmd(self, cmd):
return utils.system(cmd, ignore_status = True)
def pathname_must_exist(self, pathname):
pathname = self.replace_card_index(pathname)
if not os.path.exists(pathname):
logging.error("File missing: '%s'", pathname)
return False
return True
# Returns (codec, card_index)
def get_codec(self):
# When the codec cannot be determined, the whole test cannot
# proceed. The unknown codec name must be added to 'codecs'
# below, and the associated attributes must be put into
# 'codec_info' above.
codecs = [ 'ALC272', # Mario, Alex
'WM8903', # Seaboard, Aebl, Kaen, Asymptote
'ALC269VB', # ZGB
'Cirrus Analog' # Stumpy
]
for codec in codecs:
found, index = self.find_card(codec)
if found:
return codec, index
raise error.TestError('Unable to determine sound codec.')
def get_codec_basename(self, codec):
return codec.replace(' ', '_')
def get_data_pathname(self, filename):
return os.path.join(self.bindir, filename)
def validate_files(self, files_list):
errors = 0
for f in files_list:
if not self.pathname_must_exist(f):
errors += 1
return errors
def validate_codec(self, codec):
err_str = ''
errors = self.validate_files(codec['files'])
if errors:
err_str += " files: %d" % errors
if err_str != '':
err_str = "(%s)%s" % (self._codec_basename, err_str)
return err_str
def read_codec_data(self, codec):
self._codec_basename = self.get_codec_basename(codec)
# Read files which must be present.
pathname = self.get_data_pathname(self._codec_basename + ".files")
self.codec_info[codec]['files'] = [line.strip() for line in
open(pathname)]
def run_once(self):
codec, self.card_index = self.get_codec()
self.read_codec_data(codec)
err_str = ''
if codec in self.codec_info:
err_str += self.validate_codec(self.codec_info['ALL'])
err_str += self.validate_codec(self.codec_info[codec])
if err_str != '':
raise error.TestError("codec validation failed. %s" %
(err_str))
else:
raise error.TestError("No test info for codec '%s'." % (codec))