| Index: client/site_tests/logging_CrashSender/logging_CrashSender.py
|
| diff --git a/client/site_tests/logging_CrashSender/logging_CrashSender.py b/client/site_tests/logging_CrashSender/logging_CrashSender.py
|
| index cd558cf3ccd7eb4e54d824e64e0965325efa5b98..feb952bb16c2ca2c33597f975f26180f2a41d0cc 100644
|
| --- a/client/site_tests/logging_CrashSender/logging_CrashSender.py
|
| +++ b/client/site_tests/logging_CrashSender/logging_CrashSender.py
|
| @@ -2,24 +2,39 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -import logging, os
|
| +import logging, os, re
|
| from autotest_lib.client.bin import site_crash_test, site_utils, test
|
| from autotest_lib.client.common_lib import error, utils
|
|
|
| +_25_HOURS_AGO = -25 * 60 * 60
|
| _CRASH_SENDER_CRON_PATH = '/etc/cron.hourly/crash_sender.hourly'
|
| _DAILY_RATE_LIMIT = 32
|
| _MIN_UNIQUE_TIMES = 4
|
| +_HWCLASS_PATH = '/sys/devices/platform/chromeos_acpi/HWID'
|
| _SECONDS_SEND_SPREAD = 3600
|
|
|
| -
|
| class logging_CrashSender(site_crash_test.CrashTest):
|
| version = 1
|
|
|
|
|
| - def _test_sender_simple_minidump(self):
|
| - """Test sending a single minidump crash report."""
|
| + def _check_hardware_info(self, result):
|
| + # Get board name
|
| + lsb_release = utils.read_file('/etc/lsb-release')
|
| + board_match = re.search(r'CHROMEOS_RELEASE_BOARD=(.*)', lsb_release)
|
| + if not ('Board: %s' % board_match.group(1)) in result['output']:
|
| + raise error.TestFail('Missing board name %s in output' %
|
| + board_match.group(1))
|
| + # Get hwid
|
| + hwclass = 'unknown'
|
| + if os.path.exists(_HWCLASS_PATH):
|
| + hwclass = utils.read_file(_HWCLASS_PATH)
|
| + if not ('HWClass: %s' % hwclass) in result['output']:
|
| + raise error.TestFail('Missing hwclass %s in output' % hwclass)
|
| +
|
| +
|
| + def _check_simple_minidump_send(self, report):
|
| self._set_sending(True)
|
| - result = self._call_sender_one_crash()
|
| + result = self._call_sender_one_crash(report=report)
|
| if (result['report_exists'] or
|
| result['rate_count'] != 1 or
|
| not result['send_attempt'] or
|
| @@ -27,15 +42,40 @@ class logging_CrashSender(site_crash_test.CrashTest):
|
| result['sleep_time'] < 0 or
|
| result['sleep_time'] >= _SECONDS_SEND_SPREAD or
|
| result['report_kind'] != 'minidump' or
|
| - result['exec_name'] != 'fake'):
|
| + result['report_payload'] != '/var/spool/crash/fake.dmp' or
|
| + result['exec_name'] != 'fake' or
|
| + not 'Version: my_ver' in result['output']):
|
| raise error.TestFail('Simple minidump send failed')
|
| + self._check_hardware_info(result)
|
| +
|
| +
|
| + def _test_sender_simple_minidump(self):
|
| + """Test sending a single minidump crash report."""
|
| + self._check_simple_minidump_send(None)
|
| +
|
| +
|
| + def _shift_file_mtime(self, path, delta):
|
| + statinfo = os.stat(path)
|
| + os.utime(path, (statinfo.st_atime,
|
| + statinfo.st_mtime + delta))
|
| +
|
| +
|
| + def _test_sender_simple_old_minidump(self):
|
| + """Test that old minidumps and metadata are sent."""
|
| + self._set_sending(True)
|
| + dmp_path = self.write_crash_dir_entry('fake.dmp', '')
|
| + meta_path = self.write_fake_meta('fake.meta', 'fake')
|
| + self._shift_file_mtime(dmp_path, _25_HOURS_AGO)
|
| + self._shift_file_mtime(meta_path, _25_HOURS_AGO)
|
| + self._check_simple_minidump_send(meta_path)
|
|
|
|
|
| def _test_sender_simple_kernel_crash(self):
|
| """Test sending a single kcrash report."""
|
| self._set_sending(True)
|
| - kcrash_fake_report = self.create_fake_crash_dir_entry(
|
| - 'kernel.today.kcrash')
|
| + kcrash_fake_report = self.write_crash_dir_entry(
|
| + 'kernel.today.kcrash', '')
|
| + self.write_fake_meta('kernel.today.meta', 'kernel')
|
| result = self._call_sender_one_crash(report=kcrash_fake_report)
|
| if (result['report_exists'] or
|
| result['rate_count'] != 1 or
|
| @@ -44,8 +84,11 @@ class logging_CrashSender(site_crash_test.CrashTest):
|
| result['sleep_time'] < 0 or
|
| result['sleep_time'] >= _SECONDS_SEND_SPREAD or
|
| result['report_kind'] != 'kcrash' or
|
| + (result['report_payload'] !=
|
| + '/var/spool/crash/kernel.today.kcrash') or
|
| result['exec_name'] != 'kernel'):
|
| raise error.TestFail('Simple kcrash send failed')
|
| + self._check_hardware_info(result)
|
|
|
|
|
| def _test_sender_pausing(self):
|
| @@ -100,9 +143,7 @@ class logging_CrashSender(site_crash_test.CrashTest):
|
| # Set one rate file a day earlier and verify can send
|
| rate_files = os.listdir(self._CRASH_SENDER_RATE_DIR)
|
| rate_path = os.path.join(self._CRASH_SENDER_RATE_DIR, rate_files[0])
|
| - statinfo = os.stat(rate_path)
|
| - os.utime(rate_path, (statinfo.st_atime,
|
| - statinfo.st_mtime - (60 * 60 * 25)))
|
| + self._shift_file_mtime(rate_path, _25_HOURS_AGO)
|
| utils.system('ls -l ' + self._CRASH_SENDER_RATE_DIR)
|
| result = self._call_sender_one_crash()
|
| if (not result['send_attempt'] or
|
| @@ -140,32 +181,43 @@ class logging_CrashSender(site_crash_test.CrashTest):
|
| 'sending')
|
|
|
|
|
| - def _test_sender_leaves_core_files(self):
|
| - """Test that a core file is left in the send directory.
|
| -
|
| - Core files will only persist for developer/testing images. We
|
| - should never remove such a file."""
|
| + def _test_sender_orphaned_files(self):
|
| + """Test that payload and unknown files that are old are removed."""
|
| + core_file = self.write_crash_dir_entry('random1.core', '')
|
| + unknown_file = self.write_crash_dir_entry('.unknown', '')
|
| + # As new files, we expect crash_sender to leave these alone.
|
| self._set_sending(True)
|
| - # Call prepare function to make sure the directory exists.
|
| - core_name = 'something.ending.with.core'
|
| - core_path = self.create_fake_crash_dir_entry(core_name)
|
| - result = self._call_sender_one_crash()
|
| - if not 'Ignoring core file.' in result['output']:
|
| - raise error.TestFail('Expected ignoring core file message')
|
| - if not os.path.exists(core_path):
|
| - raise error.TestFail('Core file was removed')
|
| + results = self._call_sender_one_crash()
|
| + if ('Removing old orphaned file' in results['output'] or
|
| + not os.path.exists(core_file) or
|
| + not os.path.exists(unknown_file)):
|
| + raise error.TestFail('New orphaned files were removed')
|
| + self._shift_file_mtime(core_file, _25_HOURS_AGO)
|
| + self._shift_file_mtime(unknown_file, _25_HOURS_AGO)
|
| + results = self._call_sender_one_crash()
|
| + if (not 'Removing old orphaned file' in results['output'] or
|
| + os.path.exists(core_file) or os.path.exists(unknown_file)):
|
| + raise error.TestFail(
|
| + 'Old orphaned files were not removed')
|
|
|
|
|
| - def _test_sender_unknown_report_kind(self):
|
| + def _test_sender_incomplete_metadata(self):
|
| + """Test that incomplete metadata file is removed once old."""
|
| + meta_file = self.write_crash_dir_entry('incomplete.meta', 'half=1')
|
| + dmp_file = self.write_crash_dir_entry('incomplete.dmp', '')
|
| + # As new files, we expect crash_sender to leave these alone.
|
| self._set_sending(True)
|
| - bad_report = self.create_fake_crash_dir_entry('fake.bad')
|
| - result = self._call_sender_one_crash(report=bad_report)
|
| - if (result['report_exists'] or
|
| - result['rate_count'] != 0 or
|
| - result['send_attempt'] or
|
| - result['send_success'] or
|
| - not 'Unknown report' in result['output']):
|
| - raise error.TestFail('Error handling of unknown report kind failed')
|
| + results = self._call_sender_one_crash()
|
| + if ('Removing recent incomplete report' in results['output'] or
|
| + not os.path.exists(meta_file) or
|
| + not os.path.exists(dmp_file)):
|
| + raise error.TestFail('New unknown files were removed')
|
| + self._shift_file_mtime(meta_file, _25_HOURS_AGO)
|
| + results = self._call_sender_one_crash()
|
| + if (not 'Removing old incomplete metadata' in results['output'] or
|
| + os.path.exists(meta_file) or os.path.exists(dmp_file)):
|
| + raise error.TestFail(
|
| + 'Old unknown/incomplete files were not removed')
|
|
|
|
|
| def _test_cron_runs(self):
|
| @@ -197,12 +249,13 @@ class logging_CrashSender(site_crash_test.CrashTest):
|
| def run_once(self):
|
| self.run_crash_tests([
|
| 'sender_simple_minidump',
|
| + 'sender_simple_old_minidump',
|
| 'sender_simple_kernel_crash',
|
| 'sender_pausing',
|
| 'sender_reports_disabled',
|
| 'sender_rate_limiting',
|
| 'sender_single_instance',
|
| 'sender_send_fails',
|
| - 'sender_leaves_core_files',
|
| - 'sender_unknown_report_kind',
|
| + 'sender_orphaned_files',
|
| + 'sender_incomplete_metadata',
|
| 'cron_runs'])
|
|
|