# 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 os, os.path, logging from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error from autotest_lib.client.common_lib.cros import chrome from autotest_lib.client.cros.crash.crash_test import CrashTest class logging_CrashServices(test.test): """Verifies crash collection for system services.""" version = 3 process_list = { '/usr/sbin/cryptohomed' : ['.core', '.dmp', '.meta'], '/usr/bin/metrics_daemon' : ['.core', '.dmp', '.meta'], '/usr/bin/powerd' : ['.core', '.dmp', '.meta', '.log'], # Removing rsyslogd until crbug.com/611786 is fixed. # '/usr/sbin/rsyslogd': ['.core', '.dmp', '.meta'], # Removing tcsd crash with reference to crbug.com/380359 # '/usr/sbin/tcsd' : ['.core', '.dmp', '.meta'], '/usr/bin/tlsdated' : ['.core', '.dmp', '.meta'], '/usr/bin/shill' : ['.core', '.dmp', '.meta'], '/usr/sbin/update_engine' : ['.core', '.dmp', '.meta', '.log'], '/usr/sbin/wpa_supplicant' : ['.core', '.dmp', '.meta'], '/sbin/session_manager' : ['.core', '.dmp', '.meta'] } def _kill_processes(self, name): """Kills the process passed as the parameter @param name: Name of the process to be killed. @returns: exit status of the kill command. """ return utils.system("killall -w -s SEGV %s" % name, ignore_status=True) def _find_crash_files(self, process_name, extension): """Find if the crash dumps with appropriate extensions are created. @param process_name: Name of the process killed. @param extension: Extension of the dump files to be created. @returns: Returns the name of the dump file. """ return self._find_file_in_path(CrashTest._SYSTEM_CRASH_DIR, process_name, extension) def _find_file_in_path(self, path, process_name, filetype): """Checks the creation of the the dump files with appropriate extensions. Also check for the file size of the dumps created. @param path: Dirctory path where the dump files are expected. @param process_name: Name of the process. @param filetype: Extension of the dump file. @returns: Name of the dump file. """ try: entries = os.listdir(path) except OSError: return None for entry in entries: (filename, ext) = os.path.splitext(entry) if ext == filetype and filename.startswith(process_name): logging.info('the path is %s', os.path) if os.path.getsize(path + '/' + entry) > 0 : return entry return None def _test_process(self, process_path, crash_extensions): """Calls a function to kill the process and then wait for the creation of the dump files. @param process_path: Path of the process to be killed. @param crash_extensions: Extension of the dump file expected. """ if self._kill_processes(process_path): raise error.TestFail("Failed to kill process %s" % process_path) process_name = os.path.basename(process_path) for crash_ext in crash_extensions: # wait for appropriate dump files in a crash directory. utils.poll_for_condition( condition=lambda: self._find_crash_files(process_name, crash_ext), desc="Waiting for %s for %s" % (crash_ext, process_path)) def run_once(self, process_path=None, crash_extensions=None): if process_path: self._test_process(process_path,crash_extensions) return with chrome.Chrome(): for process_path in self.process_list.keys(): self.job.run_test("logging_CrashServices", process_path=process_path, crash_extensions=self.process_list.get(process_path), tag=os.path.basename(process_path))