| # Copyright (c) 2013 The Chromium 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 logging |
| |
| from autotest_lib.client.cros.audio import audio_helper |
| from autotest_lib.client.cros import cros_ui_test, httpd |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.cros import power_suspend, sys_power |
| |
| _DEFAULT_NUM_CHANNELS = 2 |
| _DEFAULT_RECORD_DURATION = 5 |
| _DEFAULT_VOLUME_LEVEL = 100 |
| _DEFAULT_CAPTURE_GAIN = 2500 |
| # Minimum RMS value to pass when checking recorded file. |
| _DEFAULT_SOX_RMS_THRESHOLD = 0.08 |
| _DEFAULT_SUSPEND_DURATION = 5 |
| _DEFAULT_ITERATIONS = 2000 |
| |
| class audio_SuspendResumeStress(cros_ui_test.UITest): |
| """Verifies audio output after suspend/resume stress test.""" |
| version = 1 |
| |
| def initialize(self, |
| num_channels=_DEFAULT_NUM_CHANNELS, |
| record_duration=_DEFAULT_RECORD_DURATION, |
| volume_level=_DEFAULT_VOLUME_LEVEL, |
| capture_gain=_DEFAULT_CAPTURE_GAIN): |
| """Setup the deps for the test. |
| |
| @param num_channels: The number of channels on the device to test. |
| @param record_duration: How long of a sample to record. |
| |
| @raises error.TestError if the deps can't be run. |
| """ |
| self._volume_level = volume_level |
| self._capture_gain = capture_gain |
| self._num_channels = num_channels |
| self._cmd_rec = 'arecord -d %f -f dat' % record_duration |
| self._suspender = power_suspend.Suspender(self.resultsdir, |
| method=sys_power.do_suspend) |
| |
| super(audio_SuspendResumeStress, self).initialize('$default') |
| self._test_url = 'http://localhost:8000/play.html' |
| self._testServer = httpd.HTTPListener(8000, docroot=self.bindir) |
| self._testServer.run() |
| |
| def run_once(self): |
| """Entry point of this test.""" |
| audio_helper.set_volume_levels(self._volume_level, self._capture_gain) |
| if not audio_helper.check_loopback_dongle(): |
| raise error.TestError('Audio loopback dongle is in bad state.') |
| |
| # Record a sample of "silence" to use as a noise profile. |
| noise_file_name = audio_helper.create_wav_file(self.resultsdir, "noise") |
| audio_helper.record_sample(noise_file_name, self._cmd_rec) |
| |
| # Play the same video to test all channels. |
| for _ in xrange(_DEFAULT_ITERATIONS): |
| logging.info('Start %s audio verification before suspend.' % _) |
| self.play_media() |
| audio_helper.loopback_test_channels(noise_file_name, |
| self.resultsdir, |
| None, |
| lambda x:self.check_recorded(x, _), |
| preserve_test_file=False, |
| num_channels=self._num_channels, |
| record_command=self._cmd_rec) |
| logging.info('End %s audio verification before suspend.' % _) |
| logging.info('Start %s suspend/resume.' % _) |
| self._suspender.suspend(_DEFAULT_SUSPEND_DURATION) |
| logging.info('End %s suspend/resume.' % _) |
| logging.info('Start %s audio verification after suspend.' % _) |
| self.play_media() |
| audio_helper.loopback_test_channels(noise_file_name, |
| self.resultsdir, |
| None, |
| lambda x:self.check_recorded(x, _), |
| preserve_test_file=False, |
| num_channels=self._num_channels, |
| record_command=self._cmd_rec) |
| logging.info('End %s audio verification after suspend.' % _) |
| |
| def play_media(self): |
| """Plays a media file in Chromium. |
| """ |
| logging.info('Playing mp3 file infinite.') |
| self.pyauto.NavigateToURL(self._test_url) |
| |
| def check_recorded(self, sox_output, test_iteration): |
| """Checks if the calculated RMS value is expected. |
| |
| @param sox_output: The output from sox stat command. |
| @param test_iteration: The iteration during the test failed. |
| |
| @raises error.TestError if RMS amplitude can't be parsed. |
| the threshold. |
| """ |
| rms_val = audio_helper.get_audio_rms(sox_output) |
| |
| # In case we don't get a valid RMS value. |
| if rms_val is None: |
| raise error.TestError( |
| 'Failed to generate an audio RMS value from playback.') |
| |
| logging.info('Got audio RMS value of %f. Minimum pass is %f.', |
| rms_val, _DEFAULT_SOX_RMS_THRESHOLD) |
| if rms_val < _DEFAULT_SOX_RMS_THRESHOLD: |
| raise error.TestFail( |
| ('Audio RMS value %f too low. Minimum pass is %f.' |
| 'Test iteration: %s.') % |
| (rms_val, _DEFAULT_SOX_RMS_THRESHOLD, test_iteration)) |