132 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| # Copyright 2015 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 logging
 | |
| import os
 | |
| import time
 | |
| 
 | |
| from autotest_lib.client.bin import test
 | |
| from autotest_lib.client.bin import utils
 | |
| from autotest_lib.client.common_lib.cros import chrome
 | |
| from autotest_lib.client.common_lib import error
 | |
| from autotest_lib.client.cros.audio import cras_utils
 | |
| 
 | |
| _CRASH_PATH = '/var/spool/crash'
 | |
| _JS = """
 | |
| var c = new AudioContext();
 | |
| var o = c.createOscillator();
 | |
| o.connect(c.destination); o.start();
 | |
| """
 | |
| 
 | |
| class audio_CrasSanity(test.test):
 | |
|     """Verifies cras sanity using its status, active streams and crashes"""
 | |
| 
 | |
|     version = 1
 | |
|     _check = {'crashes_on_boot': False,
 | |
|               'stream_activation': False,
 | |
|               'cras_status': False,
 | |
|               'crashes_at_end': False
 | |
|              }
 | |
| 
 | |
|     def run_once(self):
 | |
|         # Check for existing cras crashes which might occur during UI bring up.
 | |
|         # TODO: (rohitbm) check if we need to reboot the DUT before the test
 | |
|         #       start to verify cras crashes during boot.
 | |
|         existing_crash_reports = self.collect_cras_crash()
 | |
|         if len(existing_crash_reports) == 0:
 | |
|             self._check['crashes_on_boot'] = True
 | |
| 
 | |
|         # Capturing cras pid before startig the test.
 | |
|         cras_pid_1 = utils.get_oldest_pid_by_name('/usr/bin/cras')
 | |
| 
 | |
|         with chrome.Chrome(init_network_controller=True) as self._cr:
 | |
|             # Push the 1st stream
 | |
|             self.push_new_stream(self._cr.browser.tabs.New())
 | |
| 
 | |
|             # Capturing cras pid before opening a new set of audio streams.
 | |
|             cras_pid_2 = utils.get_oldest_pid_by_name('/usr/bin/cras')
 | |
| 
 | |
|             # Push the 2nd stream
 | |
|             self.push_new_stream(self._cr.browser.tabs.New())
 | |
| 
 | |
|             # Let's play audio for sometime to ensure that
 | |
|             # long playback is good.
 | |
|             time.sleep(10)
 | |
| 
 | |
|             total_tests = 2
 | |
|             active_streams = cras_utils.get_active_stream_count()
 | |
|             logging.debug(
 | |
|                 'Number of active streams after opening all tabs: %d.',
 | |
|                 active_streams)
 | |
|             if active_streams >= total_tests:
 | |
|                 self._check['stream_activation'] = True
 | |
| 
 | |
|             # Capturing cras pid after opening all audio/video streams.
 | |
|             cras_pid_3 = utils.get_oldest_pid_by_name('/usr/bin/cras')
 | |
| 
 | |
|             # Close all open audio streams.
 | |
|             while total_tests > 0:
 | |
|                 self._cr.browser.tabs[total_tests].Close()
 | |
|                 total_tests -= 1
 | |
|                 time.sleep(1)
 | |
|             active_streams = cras_utils.get_active_stream_count()
 | |
|             logging.debug(
 | |
|                 'Number of active streams after closing all tabs: %d.',
 | |
|                 active_streams)
 | |
| 
 | |
|             # Capturing cras pid after closing all audio/stream streams.
 | |
|             cras_pid_4 = utils.get_oldest_pid_by_name('/usr/bin/cras')
 | |
| 
 | |
|             if cras_pid_1 == cras_pid_2 == cras_pid_3 == cras_pid_4:
 | |
|                 self._check['cras_status'] = True
 | |
| 
 | |
|         new_crash_reports = self.collect_cras_crash()
 | |
|         new_reports = list(set(new_crash_reports) -
 | |
|                            set(existing_crash_reports))
 | |
|         if len(new_reports) == 0:
 | |
|             self._check['crashes_at_end'] = True
 | |
| 
 | |
|         err_msg = ''
 | |
|         if self._check.values().count(False) > 0:
 | |
|             if not self._check['crashes_on_boot']:
 | |
|                 err_msg = ('1. Found cras crashes on boot: %s.\n'
 | |
|                            % existing_crash_reports)
 | |
|             if not self._check['stream_activation']:
 | |
|                 err_msg += ('2. CRAS stream count is not matching with '
 | |
|                             'number of streams.\n')
 | |
|             if not self._check['cras_status']:
 | |
|                 err_msg += ('CRAS PID changed during the test. CRAS might be '
 | |
|                             'crashing while adding/removing streams.\n')
 | |
|             if not self._check['crashes_at_end']:
 | |
|                 err_msg += ('Found cras crashes at the end of the test : %s.' %
 | |
|                             new_reports)
 | |
|             raise error.TestError(err_msg)
 | |
| 
 | |
| 
 | |
|     def push_new_stream(self, tab):
 | |
|         """Starts next audio stream from self._streams list.
 | |
| 
 | |
|         @param tab: tab to open an audio stream.
 | |
|         """
 | |
|         tab.Activate()
 | |
|         tab.Navigate("file:///")
 | |
|         tab.ExecuteJavaScript(_JS)
 | |
|         time.sleep(1) # Adding a delay so cras can update the active count.
 | |
| 
 | |
| 
 | |
|     def collect_cras_crash(self):
 | |
|         """Check for cras crashes.
 | |
| 
 | |
|         @return a list of cras crash reports found.
 | |
|         """
 | |
| 
 | |
|         crash_reports = []
 | |
|         if not os.path.isdir(_CRASH_PATH):
 | |
|             logging.debug('No cras crash detected!')
 | |
|         else:
 | |
|             cras_reports = os.listdir(_CRASH_PATH)
 | |
|             crash_reports = [report for report in cras_reports
 | |
|                              if report.startswith('cras')]
 | |
|         return crash_reports
 |