普通文本  |  101行  |  3.57 KB

# 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)