Home | History | Annotate | Download | only in sound_infrastructure
      1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import glob
      6 import os
      7 import re
      8 import stat
      9 import subprocess
     10 
     11 from autotest_lib.client.common_lib import error
     12 from autotest_lib.client.bin import test
     13 from autotest_lib.client.bin import utils
     14 
     15 _SND_DEV_DIR = '/dev/snd/'
     16 _SND_DEFAULT_MASK = 'controlC*'
     17 
     18 class sound_infrastructure(test.test):
     19     """
     20     Tests that the expected sound infrastructure is present.
     21 
     22     Check that at least one playback and capture device exists and that their
     23     permissions are configured properly.
     24 
     25     """
     26     version = 2
     27     _NO_PLAYBACK_BOARDS_LIST = []
     28     _NO_RECORDER_BOARDS_LIST = ['veyron_mickey']
     29     _NO_AUDIO_DEVICE_LIST = ['veyron_rialto']
     30 
     31     def check_snd_dev_perms(self, filename):
     32         desired_mode = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP |
     33                         stat.S_IWGRP | stat.S_IFCHR)
     34         st = os.stat(filename)
     35         if (st.st_mode != desired_mode):
     36             raise error.TestFail("Incorrect permissions for %s" % filename)
     37 
     38     def check_sound_files(self, playback=True, record=True):
     39         """Checks sound files present in snd directory.
     40 
     41         @param playback: Checks playback device.
     42         @param record: Checks record device.
     43 
     44         @raises: error.TestFail if sound file is missing.
     45 
     46         """
     47         patterns = {'^controlC(\d+)': False}
     48         if playback:
     49             patterns['^pcmC(\d+)D(\d+)p$'] = False
     50         if record:
     51             patterns['^pcmC(\d+)D(\d+)c$'] = False
     52 
     53         filenames = os.listdir(_SND_DEV_DIR)
     54 
     55         for filename in filenames:
     56             for pattern in patterns:
     57                 if re.match(pattern, filename):
     58                     patterns[pattern] = True
     59                     self.check_snd_dev_perms(_SND_DEV_DIR + filename)
     60 
     61         for pattern in patterns:
     62             if not patterns[pattern]:
     63                 raise error.TestFail("Missing device %s" % pattern)
     64 
     65     def check_device_list(self, playback=True, record=True):
     66         """Checks sound card and device list by alsa utils command.
     67 
     68         @param playback: Checks playback sound card and devices.
     69         @param record: Checks record sound card and devices.
     70 
     71         @raises: error.TestFail if no playback/record devices found.
     72 
     73         """
     74         no_cards_pattern = '.*no soundcards found.*'
     75         if playback:
     76             aplay = subprocess.Popen(["aplay", "-l"], stderr=subprocess.PIPE)
     77             aplay_list = aplay.communicate()[1]
     78             if aplay.returncode or re.match(no_cards_pattern, aplay_list):
     79                 raise error.TestFail("No playback devices found by aplay")
     80 
     81         if record:
     82             no_cards_pattern = '.*no soundcards found.*'
     83             arecord = subprocess.Popen(
     84                     ["arecord", "-l"], stderr=subprocess.PIPE)
     85             arecord_list = arecord.communicate()[1]
     86             if arecord.returncode or re.match(no_cards_pattern, arecord_list):
     87                 raise error.TestFail("No record devices found by arecord")
     88 
     89     def run_once(self):
     90         board = utils.get_board().lower()
     91         snd_control = len(glob.glob(_SND_DEV_DIR + _SND_DEFAULT_MASK))
     92         if board in self._NO_AUDIO_DEVICE_LIST:
     93             if snd_control:
     94                 raise error.TestError('%s is not supposed to have sound control!' % board)
     95             else:
     96                 return
     97         record = board not in self._NO_RECORDER_BOARDS_LIST
     98         playback = board not in self._NO_PLAYBACK_BOARDS_LIST
     99         self.check_sound_files(playback, record)
    100         self.check_device_list(playback, record)
    101