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 |