Chromium Code Reviews| Index: client/site_tests/logging_UserCrash/logging_UserCrash.py |
| diff --git a/client/site_tests/logging_UserCrash/logging_UserCrash.py b/client/site_tests/logging_UserCrash/logging_UserCrash.py |
| index 978bf124d9aba5aef9c938dccd9fb546597ec032..a226612a04949b1292de26176119170d2ac430ae 100644 |
| --- a/client/site_tests/logging_UserCrash/logging_UserCrash.py |
| +++ b/client/site_tests/logging_UserCrash/logging_UserCrash.py |
| @@ -7,6 +7,8 @@ from signal import SIGSEGV |
| from autotest_lib.client.bin import site_crash_test, site_utils, test |
| from autotest_lib.client.common_lib import error, utils |
| +_COLLECTION_ERROR_SIGNATURE = 'crash_reporter-user-collection' |
| +_CORE2MD_PATH = '/usr/bin/core2md' |
| _CORE_PATTERN = '/proc/sys/kernel/core_pattern' |
| _LEAVE_CORE_PATH = '/root/.leave_core' |
| _MAX_CRASH_DIRECTORY_SIZE = 32 |
| @@ -155,7 +157,7 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| stderr=subprocess.PIPE) |
| output = crasher.communicate()[1] |
| logging.debug('Output from %s: %s' % |
| - (self._crasher_path, output)) |
| + (crasher_command, output)) |
| # Grab the pid from the process output. We can't just use |
| # crasher.pid unfortunately because that may be the PID of su. |
| @@ -168,7 +170,7 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| if consent: |
| handled_string = 'handling' |
| else: |
| - handled_string = 'ignoring' |
| + handled_string = 'ignoring - no consent' |
| expected_message = ( |
| 'Received crash notification for %s[%d] sig 11 (%s)' % |
| (basename, pid, handled_string)) |
| @@ -226,27 +228,31 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| self._verify_stack(stack, basename, from_crash_reporter) |
| - def _check_generated_minidump_sending(self, meta_path, minidump_path, |
| - username, crasher_basename, |
| - will_syslog_give_name): |
| + def _check_generated_report_sending(self, meta_path, payload_path, |
| + username, exec_name, report_kind, |
| + expected_sig=None): |
| # Now check that the sending works |
| result = self._call_sender_one_crash( |
| username=username, |
| - report=os.path.basename(minidump_path)) |
| + report=os.path.basename(payload_path)) |
| if (not result['send_attempt'] or not result['send_success'] or |
| result['report_exists']): |
| - raise error.TestFail('Minidump not sent properly') |
| - if will_syslog_give_name: |
| - if result['exec_name'] != crasher_basename: |
| - raise error.TestFail('Executable name incorrect') |
| - if result['report_kind'] != 'minidump': |
| + raise error.TestFail('Report not sent properly') |
| + if result['exec_name'] != exec_name: |
| + raise error.TestFail('Executable name incorrect') |
| + if result['report_kind'] != report_kind: |
| raise error.TestFail('Expected a minidump report') |
| - if result['report_payload'] != minidump_path: |
| + if result['report_payload'] != payload_path: |
| raise error.TestFail('Sent the wrong minidump payload') |
| if result['meta_path'] != meta_path: |
| raise error.TestFail('Used the wrong meta file') |
| - if result['sig'] is not None: |
| - raise error.TestFail('User crash should not have signature') |
| + if expected_sig is None: |
| + if result['sig'] is not None: |
| + raise error.TestFail('Report should not have signature') |
| + else: |
| + if not 'sig' in result or result['sig'] != expected_sig: |
| + raise error.TestFail('Report signature mismatch: %s vs %s' % |
| + (result['sig'], expected_sig)) |
| # Check version matches. |
| lsb_release = utils.read_file('/etc/lsb-release') |
| @@ -256,26 +262,22 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| version_match.group(1)) |
| - def _check_crashing_process(self, username, consent=True): |
| + def _run_crasher_process_and_analyze(self, username, |
| + cause_crash=True, consent=True): |
| self._log_reader.set_start_by_current() |
| - result = self._run_crasher_process(username, consent=consent) |
| - |
| - if not result['crashed']: |
| - raise error.TestFail('crasher did not do its job of crashing: %d' % |
| - result['returncode']) |
| + result = self._run_crasher_process(username, cause_crash=cause_crash, |
| + consent=consent) |
| - if not result['crash_reporter_caught']: |
| - logging.debug('Messages that should have included segv: %s' % |
| - self._log_reader.get_logs()) |
| - raise error.TestFail('Did not find segv message') |
| + if not result['crashed'] or not result['crash_reporter_caught']: |
| + return result; |
| crash_dir = self._get_crash_dir(username) |
| if not consent: |
| if os.path.exists(crash_dir): |
| raise error.TestFail('Crash directory should not exist') |
| - return |
| + return result |
| crash_contents = os.listdir(crash_dir) |
| basename = os.path.basename(self._crasher_path) |
| @@ -283,6 +285,7 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| breakpad_minidump = None |
| crash_reporter_minidump = None |
| crash_reporter_meta = None |
| + crash_reporter_log = None |
| self._check_crash_directory_permissions(crash_dir) |
| @@ -302,9 +305,15 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| elif (filename.startswith(basename) and |
| filename.endswith('.meta')): |
| if not crash_reporter_meta is None: |
| - raise error.TestFail('Crash reported wrote multiple ' |
| + raise error.TestFail('Crash reporter wrote multiple ' |
| 'meta files') |
| crash_reporter_meta = os.path.join(crash_dir, filename) |
| + elif (filename.startswith(basename) and |
| + filename.endswith('.log')): |
| + if not crash_reporter_log is None: |
| + raise error.TestFail('Crash reporter wrote multiple ' |
| + 'log files') |
| + crash_reporter_log = os.path.join(crash_dir, filename) |
| else: |
| # This appears to be a breakpad created minidump. |
| if not breakpad_minidump is None: |
| @@ -314,33 +323,57 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| if breakpad_minidump: |
| raise error.TestFail('%s did generate breakpad minidump' % basename) |
| - if not crash_reporter_minidump: |
| - raise error.TestFail('crash reporter did not generate minidump') |
| - |
| if not crash_reporter_meta: |
| raise error.TestFail('crash reporter did not generate meta') |
| + result['minidump'] = crash_reporter_minidump |
| + result['basename'] = basename |
| + result['meta'] = crash_reporter_meta |
| + result['log'] = crash_reporter_log |
| + return result |
| + |
| + |
| + def _check_crashed_and_caught(self, result): |
| + if not result['crashed']: |
| + raise error.TestFail('crasher did not do its job of crashing: %d' % |
| + result['returncode']) |
| + |
| + if not result['crash_reporter_caught']: |
| + logging.debug('Messages that should have included segv: %s' % |
| + self._log_reader.get_logs()) |
| + raise error.TestFail('Did not find segv message') |
| + |
| + |
| + def _check_crashing_process(self, username, consent=True): |
| + result = self._run_crasher_process_and_analyze(username, |
| + consent=consent) |
| + |
| + self._check_crashed_and_caught(result) |
| + |
| + if not consent: |
| + return |
| + |
| + if not result['minidump']: |
| + raise error.TestFail('crash reporter did not generate minidump') |
| + |
| if not self._log_reader.can_find('Stored minidump to ' + |
| - crash_reporter_minidump): |
| + result['minidump']): |
| raise error.TestFail('crash reporter did not announce minidump') |
| - if crash_reporter_minidump: |
| - self._check_minidump_stackwalk(crash_reporter_minidump, |
| - basename, |
| - from_crash_reporter=True) |
| - will_syslog_give_name = True |
| - |
| - self._check_generated_minidump_sending(crash_reporter_meta, |
| - crash_reporter_minidump, |
| - username, |
| - basename, |
| - will_syslog_give_name) |
| + self._check_minidump_stackwalk(result['minidump'], |
| + result['basename'], |
| + from_crash_reporter=True) |
| + self._check_generated_report_sending(result['meta'], |
| + result['minidump'], |
| + username, |
| + result['basename'], |
| + 'minidump') |
| def _test_no_crash(self): |
| """Test a program linked against libcrash_dumper can exit normally.""" |
| self._log_reader.set_start_by_current() |
| - result = self._run_crasher_process(username='root', |
| - cause_crash=False) |
| + result = self._run_crasher_process_and_analyze(username='root', |
| + cause_crash=False) |
| if (result['crashed'] or |
| result['crash_reporter_caught'] or |
| result['returncode'] != 0): |
| @@ -409,6 +442,48 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| crash_dir_size) |
| + def _check_collection_failure(self, test_option, failure_string): |
| + # Add parameter to core_pattern. |
| + old_core_pattern = utils.read_file(_CORE_PATTERN)[:-1] |
| + try: |
| + utils.system('echo "%s %s" > %s' % (old_core_pattern, test_option, |
|
petkov
2010/10/28 22:30:50
You could use utils.write_one_line here and below.
|
| + _CORE_PATTERN)) |
| + result = self._run_crasher_process_and_analyze('root', |
| + consent=True) |
| + self._check_crashed_and_caught(result) |
| + if not self._log_reader.can_find(failure_string): |
| + raise error.TestFail('Did not find fail string in log %s' % |
| + failure_string) |
| + if result['minidump']: |
| + raise error.TestFail('failed collection resulted in minidump') |
| + if not result['log']: |
| + raise error.TestFail('failed collection had no log') |
| + log_contents = utils.read_file(result['log']) |
| + if not log_contents.startswith(failure_string): |
| + raise error.TestFail('Expected logged error ' |
| + '\"%s\" was \"%s\"' % |
| + (failure_string, log_contents)) |
| + self._check_generated_report_sending(result['meta'], |
| + result['log'], |
| + 'root', |
| + result['basename'], |
| + 'log', |
| + _COLLECTION_ERROR_SIGNATURE) |
| + finally: |
| + utils.system('echo "%s" > %s' % (old_core_pattern, _CORE_PATTERN)) |
| + |
| + |
| + def _test_core2md_failure(self): |
| + self._check_collection_failure('--core2md_failure_test', |
| + 'Problem during %s [result=1]: Usage:' % |
| + _CORE2MD_PATH) |
| + |
| + |
| + def _test_internal_directory_failure(self): |
| + self._check_collection_failure('--directory_failure_test', |
| + 'Purposefully failing to create') |
| + |
| + |
| def _check_core_file_persisting(self, expect_persist): |
| self._log_reader.set_start_by_current() |
| @@ -481,6 +556,8 @@ class logging_UserCrash(site_crash_test.CrashTest): |
| 'root_crasher', |
| 'root_crasher_no_consent', |
| 'max_enqueued_crashes', |
| + 'core2md_failure', |
| + 'internal_directory_failure', |
| 'core_file_persists_in_debug', |
| 'core_file_removed_in_production'], |
| initialize_crash_reporter = True) |