Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import grp, logging, os, pwd, re, stat, subprocess | 5 import grp, logging, os, pwd, re, stat, subprocess |
| 6 from signal import SIGSEGV | 6 from signal import SIGSEGV |
| 7 from autotest_lib.client.bin import site_crash_test, site_utils, test | 7 from autotest_lib.client.bin import site_crash_test, site_utils, test |
| 8 from autotest_lib.client.common_lib import error, utils | 8 from autotest_lib.client.common_lib import error, utils |
| 9 | 9 |
| 10 _COLLECTION_ERROR_SIGNATURE = 'crash_reporter-user-collection' | 10 _COLLECTION_ERROR_SIGNATURE = 'crash_reporter-user-collection' |
| 11 _CORE2MD_PATH = '/usr/bin/core2md' | 11 _CORE2MD_PATH = '/usr/bin/core2md' |
| 12 _CORE_PATTERN = '/proc/sys/kernel/core_pattern' | |
| 13 _LEAVE_CORE_PATH = '/root/.leave_core' | 12 _LEAVE_CORE_PATH = '/root/.leave_core' |
| 14 _MAX_CRASH_DIRECTORY_SIZE = 32 | 13 _MAX_CRASH_DIRECTORY_SIZE = 32 |
| 15 | 14 |
| 16 | 15 |
| 17 class logging_UserCrash(site_crash_test.CrashTest): | 16 class logging_UserCrash(site_crash_test.CrashTest): |
| 18 version = 1 | 17 version = 1 |
| 19 | 18 |
| 20 | 19 |
| 21 def setup(self): | 20 def setup(self): |
| 22 os.chdir(self.srcdir) | 21 os.chdir(self.srcdir) |
| 23 utils.make('clean all') | 22 utils.make('clean all') |
| 24 | 23 |
| 25 | 24 |
| 26 def _test_reporter_startup(self): | 25 def _test_reporter_startup(self): |
| 27 """Test that the core_pattern is set up by crash reporter.""" | 26 """Test that the core_pattern is set up by crash reporter.""" |
| 28 output = utils.read_file(_CORE_PATTERN).rstrip() | 27 # Turn off crash filtering so we see the original setting. |
| 28 self.disable_crash_filtering() | |
| 29 output = utils.read_file(self._CORE_PATTERN).rstrip() | |
| 29 expected_core_pattern = ('|%s --signal=%%s --pid=%%p' % | 30 expected_core_pattern = ('|%s --signal=%%s --pid=%%p' % |
| 30 self._CRASH_REPORTER_PATH) | 31 self._CRASH_REPORTER_PATH) |
| 31 if output != expected_core_pattern: | 32 if output != expected_core_pattern: |
| 32 raise error.TestFail('core pattern should have been %s, not %s' % | 33 raise error.TestFail('core pattern should have been %s, not %s' % |
| 33 (expected_core_pattern, output)) | 34 (expected_core_pattern, output)) |
| 34 | 35 |
| 35 self._log_reader.set_start_by_reboot(-1) | 36 self._log_reader.set_start_by_reboot(-1) |
| 36 | 37 |
| 37 if not self._log_reader.can_find('Enabling user crash handling'): | 38 if not self._log_reader.can_find('Enabling user crash handling'): |
| 38 raise error.TestFail( | 39 raise error.TestFail( |
| 39 'user space crash handling was not started during last boot') | 40 'user space crash handling was not started during last boot') |
| 40 | 41 |
| 41 | 42 |
| 42 def _test_reporter_shutdown(self): | 43 def _test_reporter_shutdown(self): |
| 43 """Test the crash_reporter shutdown code works.""" | 44 """Test the crash_reporter shutdown code works.""" |
| 44 self._log_reader.set_start_by_current() | 45 self._log_reader.set_start_by_current() |
| 45 utils.system('%s --clean_shutdown' % self._CRASH_REPORTER_PATH) | 46 utils.system('%s --clean_shutdown' % self._CRASH_REPORTER_PATH) |
| 46 output = utils.read_file(_CORE_PATTERN).rstrip() | 47 output = utils.read_file(self._CORE_PATTERN).rstrip() |
| 47 if output != 'core': | 48 if output != 'core': |
| 48 raise error.TestFail('core pattern should have been core, not %s' % | 49 raise error.TestFail('core pattern should have been core, not %s' % |
| 49 output) | 50 output) |
| 50 | 51 |
| 51 | 52 |
| 52 def _prepare_crasher(self): | 53 def _prepare_crasher(self): |
| 53 """Extract the crasher and set its permissions. | 54 """Extract the crasher and set its permissions. |
| 54 | 55 |
| 55 crasher is only gzipped to subvert Portage stripping. | 56 crasher is only gzipped to subvert Portage stripping. |
| 56 """ | 57 """ |
| 58 self.enable_crash_filtering('crasher_nobreakpad') | |
| 57 self._crasher_path = os.path.join(self.srcdir, 'crasher_nobreakpad') | 59 self._crasher_path = os.path.join(self.srcdir, 'crasher_nobreakpad') |
| 58 utils.system('cd %s; tar xzf crasher.tgz-unmasked' % | 60 utils.system('cd %s; tar xzf crasher.tgz-unmasked' % |
| 59 self.srcdir) | 61 self.srcdir) |
| 60 | 62 |
| 61 | 63 |
| 62 def _populate_symbols(self): | 64 def _populate_symbols(self): |
| 63 """Set up Breakpad's symbol structure. | 65 """Set up Breakpad's symbol structure. |
| 64 | 66 |
| 65 Breakpad's minidump processor expects symbols to be in a directory | 67 Breakpad's minidump processor expects symbols to be in a directory |
| 66 hierarchy: | 68 hierarchy: |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 def _test_root_crasher(self): | 395 def _test_root_crasher(self): |
| 394 """Test a user space crash when running as root is handled.""" | 396 """Test a user space crash when running as root is handled.""" |
| 395 self._check_crashing_process('root') | 397 self._check_crashing_process('root') |
| 396 | 398 |
| 397 | 399 |
| 398 def _test_root_crasher_no_consent(self): | 400 def _test_root_crasher_no_consent(self): |
| 399 """Test that without consent no files are stored.""" | 401 """Test that without consent no files are stored.""" |
| 400 results = self._check_crashing_process('root', consent=False) | 402 results = self._check_crashing_process('root', consent=False) |
| 401 | 403 |
| 402 | 404 |
| 405 def _check_filter_crasher(self, should_receive): | |
| 406 self._log_reader.set_start_by_current() | |
| 407 crasher_basename = os.path.basename(self._crasher_path) | |
| 408 utils.system(self._crasher_path, ignore_status=True); | |
| 409 if should_receive: | |
| 410 to_find = 'Received crash notification for ' + crasher_basename | |
| 411 else: | |
| 412 to_find = 'Ignoring crash from ' + crasher_basename | |
| 413 site_utils.poll_for_condition( | |
| 414 lambda: self._log_reader.can_find(to_find), | |
| 415 timeout=10, | |
| 416 exception=error.TestError( | |
| 417 'Timeout waiting for: ' + to_find + ' in ' + | |
|
sosa
2010/10/30 06:27:59
'Timeout waiting for: %s in %s' % (to_find, blah)
| |
| 418 self._log_reader.get_logs())) | |
| 419 | |
| 420 | |
| 421 def _test_crash_filtering(self): | |
| 422 """Test that crash filtering (a feature needed for testing) works.""" | |
| 423 self._prepare_crasher() | |
| 424 crasher_basename = os.path.basename(self._crasher_path) | |
| 425 self._log_reader.set_start_by_current() | |
| 426 | |
| 427 self.enable_crash_filtering('none') | |
| 428 self._check_filter_crasher(False) | |
| 429 | |
| 430 self.enable_crash_filtering('sleep') | |
| 431 self._check_filter_crasher(False) | |
| 432 | |
| 433 self.disable_crash_filtering() | |
| 434 self._check_filter_crasher(True) | |
| 435 | |
| 436 | |
| 403 def _test_max_enqueued_crashes(self): | 437 def _test_max_enqueued_crashes(self): |
| 404 """Test that _MAX_CRASH_DIRECTORY_SIZE is enforced.""" | 438 """Test that _MAX_CRASH_DIRECTORY_SIZE is enforced.""" |
| 405 self._log_reader.set_start_by_current() | 439 self._log_reader.set_start_by_current() |
| 406 username = 'root' | 440 username = 'root' |
| 407 | 441 |
| 408 crash_dir = self._get_crash_dir(username) | 442 crash_dir = self._get_crash_dir(username) |
| 409 full_message = ('Crash directory %s already full with %d pending ' | 443 full_message = ('Crash directory %s already full with %d pending ' |
| 410 'reports' % (crash_dir, _MAX_CRASH_DIRECTORY_SIZE)) | 444 'reports' % (crash_dir, _MAX_CRASH_DIRECTORY_SIZE)) |
| 411 | 445 |
| 412 # Fill up the queue. | 446 # Fill up the queue. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 437 | 471 |
| 438 if crash_dir_size != len(os.listdir(crash_dir)): | 472 if crash_dir_size != len(os.listdir(crash_dir)): |
| 439 utils.system('ls -l %s' % crash_dir) | 473 utils.system('ls -l %s' % crash_dir) |
| 440 raise error.TestFail('expected no new files (now %d were %d)', | 474 raise error.TestFail('expected no new files (now %d were %d)', |
| 441 len(os.listdir(crash_dir)), | 475 len(os.listdir(crash_dir)), |
| 442 crash_dir_size) | 476 crash_dir_size) |
| 443 | 477 |
| 444 | 478 |
| 445 def _check_collection_failure(self, test_option, failure_string): | 479 def _check_collection_failure(self, test_option, failure_string): |
| 446 # Add parameter to core_pattern. | 480 # Add parameter to core_pattern. |
| 447 old_core_pattern = utils.read_file(_CORE_PATTERN)[:-1] | 481 old_core_pattern = utils.read_file(self._CORE_PATTERN)[:-1] |
| 448 try: | 482 try: |
| 449 utils.system('echo "%s %s" > %s' % (old_core_pattern, test_option, | 483 utils.system('echo "%s %s" > %s' % (old_core_pattern, test_option, |
| 450 _CORE_PATTERN)) | 484 self._CORE_PATTERN)) |
| 451 result = self._run_crasher_process_and_analyze('root', | 485 result = self._run_crasher_process_and_analyze('root', |
| 452 consent=True) | 486 consent=True) |
| 453 self._check_crashed_and_caught(result) | 487 self._check_crashed_and_caught(result) |
| 454 if not self._log_reader.can_find(failure_string): | 488 if not self._log_reader.can_find(failure_string): |
| 455 raise error.TestFail('Did not find fail string in log %s' % | 489 raise error.TestFail('Did not find fail string in log %s' % |
| 456 failure_string) | 490 failure_string) |
| 457 if result['minidump']: | 491 if result['minidump']: |
| 458 raise error.TestFail('failed collection resulted in minidump') | 492 raise error.TestFail('failed collection resulted in minidump') |
| 459 if not result['log']: | 493 if not result['log']: |
| 460 raise error.TestFail('failed collection had no log') | 494 raise error.TestFail('failed collection had no log') |
| 461 log_contents = utils.read_file(result['log']) | 495 log_contents = utils.read_file(result['log']) |
| 462 if not log_contents.startswith(failure_string): | 496 if not log_contents.startswith(failure_string): |
| 463 raise error.TestFail('Expected logged error ' | 497 raise error.TestFail('Expected logged error ' |
| 464 '\"%s\" was \"%s\"' % | 498 '\"%s\" was \"%s\"' % |
| 465 (failure_string, log_contents)) | 499 (failure_string, log_contents)) |
| 466 self._check_generated_report_sending(result['meta'], | 500 self._check_generated_report_sending(result['meta'], |
| 467 result['log'], | 501 result['log'], |
| 468 'root', | 502 'root', |
| 469 result['basename'], | 503 result['basename'], |
| 470 'log', | 504 'log', |
| 471 _COLLECTION_ERROR_SIGNATURE) | 505 _COLLECTION_ERROR_SIGNATURE) |
| 472 finally: | 506 finally: |
| 473 utils.system('echo "%s" > %s' % (old_core_pattern, _CORE_PATTERN)) | 507 utils.system('echo "%s" > %s' % (old_core_pattern, |
| 508 self._CORE_PATTERN)) | |
| 474 | 509 |
| 475 | 510 |
| 476 def _test_core2md_failure(self): | 511 def _test_core2md_failure(self): |
| 477 self._check_collection_failure('--core2md_failure_test', | 512 self._check_collection_failure('--core2md_failure_test', |
| 478 'Problem during %s [result=1]: Usage:' % | 513 'Problem during %s [result=1]: Usage:' % |
| 479 _CORE2MD_PATH) | 514 _CORE2MD_PATH) |
| 480 | 515 |
| 481 | 516 |
| 482 def _test_internal_directory_failure(self): | 517 def _test_internal_directory_failure(self): |
| 483 self._check_collection_failure('--directory_failure_test', | 518 self._check_collection_failure('--directory_failure_test', |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 548 # non-root, non-chronos user. | 583 # non-root, non-chronos user. |
| 549 | 584 |
| 550 def run_once(self): | 585 def run_once(self): |
| 551 self.run_crash_tests(['reporter_startup', | 586 self.run_crash_tests(['reporter_startup', |
| 552 'reporter_shutdown', | 587 'reporter_shutdown', |
| 553 'no_crash', | 588 'no_crash', |
| 554 'chronos_crasher', | 589 'chronos_crasher', |
| 555 'chronos_crasher_no_consent', | 590 'chronos_crasher_no_consent', |
| 556 'root_crasher', | 591 'root_crasher', |
| 557 'root_crasher_no_consent', | 592 'root_crasher_no_consent', |
| 593 'crash_filtering', | |
| 558 'max_enqueued_crashes', | 594 'max_enqueued_crashes', |
| 559 'core2md_failure', | 595 'core2md_failure', |
| 560 'internal_directory_failure', | 596 'internal_directory_failure', |
| 561 'core_file_persists_in_debug', | 597 'core_file_persists_in_debug', |
| 562 'core_file_removed_in_production'], | 598 'core_file_removed_in_production'], |
| 563 initialize_crash_reporter = True) | 599 initialize_crash_reporter = True) |
| OLD | NEW |