Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: client/site_tests/logging_CrashSender/logging_CrashSender.py

Issue 3454023: autotest: Test new meta files in crash directory (Closed) Base URL: http://git.chromium.org/git/autotest.git
Patch Set: Fix bug Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 logging, os 5 import logging, os, re
6 from autotest_lib.client.bin import site_crash_test, site_utils, test 6 from autotest_lib.client.bin import site_crash_test, site_utils, test
7 from autotest_lib.client.common_lib import error, utils 7 from autotest_lib.client.common_lib import error, utils
8 8
9 _25_HOURS_AGO = -25 * 60 * 60
9 _CRASH_SENDER_CRON_PATH = '/etc/cron.hourly/crash_sender.hourly' 10 _CRASH_SENDER_CRON_PATH = '/etc/cron.hourly/crash_sender.hourly'
10 _DAILY_RATE_LIMIT = 32 11 _DAILY_RATE_LIMIT = 32
11 _MIN_UNIQUE_TIMES = 4 12 _MIN_UNIQUE_TIMES = 4
13 _HWCLASS_PATH = '/sys/devices/platform/chromeos_acpi/HWID'
12 _SECONDS_SEND_SPREAD = 3600 14 _SECONDS_SEND_SPREAD = 3600
13 15
14
15 class logging_CrashSender(site_crash_test.CrashTest): 16 class logging_CrashSender(site_crash_test.CrashTest):
16 version = 1 17 version = 1
17 18
18 19
19 def _test_sender_simple_minidump(self): 20 def _check_hardware_info(self, result):
20 """Test sending a single minidump crash report.""" 21 # Get board name
22 lsb_release = utils.read_file('/etc/lsb-release')
23 board_match = re.search(r'CHROMEOS_RELEASE_BOARD=(.*)', lsb_release)
24 if not ('Board: %s' % board_match.group(1)) in result['output']:
25 raise error.TestFail('Missing board name %s in output' %
26 board_match.group(1))
27 # Get hwid
28 hwclass = 'unknown'
29 if os.path.exists(_HWCLASS_PATH):
30 hwclass = utils.read_file(_HWCLASS_PATH)
31 if not ('HWClass: %s' % hwclass) in result['output']:
32 raise error.TestFail('Missing hwclass %s in output' % hwclass)
33
34
35 def _check_simple_minidump_send(self, report):
21 self._set_sending(True) 36 self._set_sending(True)
22 result = self._call_sender_one_crash() 37 result = self._call_sender_one_crash(report=report)
23 if (result['report_exists'] or 38 if (result['report_exists'] or
24 result['rate_count'] != 1 or 39 result['rate_count'] != 1 or
25 not result['send_attempt'] or 40 not result['send_attempt'] or
26 not result['send_success'] or 41 not result['send_success'] or
27 result['sleep_time'] < 0 or 42 result['sleep_time'] < 0 or
28 result['sleep_time'] >= _SECONDS_SEND_SPREAD or 43 result['sleep_time'] >= _SECONDS_SEND_SPREAD or
29 result['report_kind'] != 'minidump' or 44 result['report_kind'] != 'minidump' or
30 result['exec_name'] != 'fake'): 45 result['report_payload'] != '/var/spool/crash/fake.dmp' or
46 result['exec_name'] != 'fake' or
47 not 'Version: my_ver' in result['output']):
31 raise error.TestFail('Simple minidump send failed') 48 raise error.TestFail('Simple minidump send failed')
49 self._check_hardware_info(result)
50
51
52 def _test_sender_simple_minidump(self):
53 """Test sending a single minidump crash report."""
54 self._check_simple_minidump_send(None)
55
56
57 def _shift_file_mtime(self, path, delta):
58 statinfo = os.stat(path)
59 os.utime(path, (statinfo.st_atime,
60 statinfo.st_mtime + delta))
61
62
63 def _test_sender_simple_old_minidump(self):
64 """Test that old minidumps and metadata are sent."""
65 self._set_sending(True)
66 dmp_path = self.write_crash_dir_entry('fake.dmp', '')
67 meta_path = self.write_fake_meta('fake.meta', 'fake')
68 self._shift_file_mtime(dmp_path, _25_HOURS_AGO)
69 self._shift_file_mtime(meta_path, _25_HOURS_AGO)
70 self._check_simple_minidump_send(meta_path)
32 71
33 72
34 def _test_sender_simple_kernel_crash(self): 73 def _test_sender_simple_kernel_crash(self):
35 """Test sending a single kcrash report.""" 74 """Test sending a single kcrash report."""
36 self._set_sending(True) 75 self._set_sending(True)
37 kcrash_fake_report = self.create_fake_crash_dir_entry( 76 kcrash_fake_report = self.write_crash_dir_entry(
38 'kernel.today.kcrash') 77 'kernel.today.kcrash', '')
78 self.write_fake_meta('kernel.today.meta', 'kernel')
39 result = self._call_sender_one_crash(report=kcrash_fake_report) 79 result = self._call_sender_one_crash(report=kcrash_fake_report)
40 if (result['report_exists'] or 80 if (result['report_exists'] or
41 result['rate_count'] != 1 or 81 result['rate_count'] != 1 or
42 not result['send_attempt'] or 82 not result['send_attempt'] or
43 not result['send_success'] or 83 not result['send_success'] or
44 result['sleep_time'] < 0 or 84 result['sleep_time'] < 0 or
45 result['sleep_time'] >= _SECONDS_SEND_SPREAD or 85 result['sleep_time'] >= _SECONDS_SEND_SPREAD or
46 result['report_kind'] != 'kcrash' or 86 result['report_kind'] != 'kcrash' or
87 (result['report_payload'] !=
88 '/var/spool/crash/kernel.today.kcrash') or
47 result['exec_name'] != 'kernel'): 89 result['exec_name'] != 'kernel'):
48 raise error.TestFail('Simple kcrash send failed') 90 raise error.TestFail('Simple kcrash send failed')
91 self._check_hardware_info(result)
49 92
50 93
51 def _test_sender_pausing(self): 94 def _test_sender_pausing(self):
52 """Test the sender returns immediately when the pause file is present. 95 """Test the sender returns immediately when the pause file is present.
53 96
54 This is testing the sender's test functionality - if this regresses, 97 This is testing the sender's test functionality - if this regresses,
55 other tests can become flaky because the cron-started sender may run 98 other tests can become flaky because the cron-started sender may run
56 asynchronously to these tests.""" 99 asynchronously to these tests."""
57 self._set_sending(False) 100 self._set_sending(False)
58 result = self._call_sender_one_crash() 101 result = self._call_sender_one_crash()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 # Now the _DAILY_RATE_LIMIT ^ th send request should fail. 136 # Now the _DAILY_RATE_LIMIT ^ th send request should fail.
94 result = self._call_sender_one_crash() 137 result = self._call_sender_one_crash()
95 if (not result['report_exists'] or 138 if (not result['report_exists'] or
96 not 'Cannot send more crashes' in result['output'] or 139 not 'Cannot send more crashes' in result['output'] or
97 result['rate_count'] != _DAILY_RATE_LIMIT): 140 result['rate_count'] != _DAILY_RATE_LIMIT):
98 raise error.TestFail('Crash rate limiting did not take effect') 141 raise error.TestFail('Crash rate limiting did not take effect')
99 142
100 # Set one rate file a day earlier and verify can send 143 # Set one rate file a day earlier and verify can send
101 rate_files = os.listdir(self._CRASH_SENDER_RATE_DIR) 144 rate_files = os.listdir(self._CRASH_SENDER_RATE_DIR)
102 rate_path = os.path.join(self._CRASH_SENDER_RATE_DIR, rate_files[0]) 145 rate_path = os.path.join(self._CRASH_SENDER_RATE_DIR, rate_files[0])
103 statinfo = os.stat(rate_path) 146 self._shift_file_mtime(rate_path, _25_HOURS_AGO)
104 os.utime(rate_path, (statinfo.st_atime,
105 statinfo.st_mtime - (60 * 60 * 25)))
106 utils.system('ls -l ' + self._CRASH_SENDER_RATE_DIR) 147 utils.system('ls -l ' + self._CRASH_SENDER_RATE_DIR)
107 result = self._call_sender_one_crash() 148 result = self._call_sender_one_crash()
108 if (not result['send_attempt'] or 149 if (not result['send_attempt'] or
109 not result['send_success'] or 150 not result['send_success'] or
110 result['rate_count'] != _DAILY_RATE_LIMIT): 151 result['rate_count'] != _DAILY_RATE_LIMIT):
111 raise error.TestFail('Crash not sent even after 25hrs pass') 152 raise error.TestFail('Crash not sent even after 25hrs pass')
112 153
113 154
114 def _test_sender_single_instance(self): 155 def _test_sender_single_instance(self):
115 """Test the sender fails to start when another instance is running. 156 """Test the sender fails to start when another instance is running.
(...skipping 17 matching lines...) Expand all
133 if not result['send_attempt'] or result['send_success']: 174 if not result['send_attempt'] or result['send_success']:
134 raise error.TestError('Did not properly cause a send failure') 175 raise error.TestError('Did not properly cause a send failure')
135 if result['rate_count'] != 1: 176 if result['rate_count'] != 1:
136 raise error.TestFail('Did not count a failed send against rate ' 177 raise error.TestFail('Did not count a failed send against rate '
137 'limiting') 178 'limiting')
138 if not result['report_exists']: 179 if not result['report_exists']:
139 raise error.TestFail('Expected minidump to be saved for later ' 180 raise error.TestFail('Expected minidump to be saved for later '
140 'sending') 181 'sending')
141 182
142 183
143 def _test_sender_leaves_core_files(self): 184 def _test_sender_orphaned_files(self):
144 """Test that a core file is left in the send directory. 185 """Test that payload and unknown files that are old are removed."""
145 186 core_file = self.write_crash_dir_entry('random1.core', '')
146 Core files will only persist for developer/testing images. We 187 unknown_file = self.write_crash_dir_entry('.unknown', '')
147 should never remove such a file.""" 188 # As new files, we expect crash_sender to leave these alone.
148 self._set_sending(True) 189 self._set_sending(True)
149 # Call prepare function to make sure the directory exists. 190 results = self._call_sender_one_crash()
150 core_name = 'something.ending.with.core' 191 if ('Removing old orphaned file' in results['output'] or
151 core_path = self.create_fake_crash_dir_entry(core_name) 192 not os.path.exists(core_file) or
152 result = self._call_sender_one_crash() 193 not os.path.exists(unknown_file)):
153 if not 'Ignoring core file.' in result['output']: 194 raise error.TestFail('New orphaned files were removed')
154 raise error.TestFail('Expected ignoring core file message') 195 self._shift_file_mtime(core_file, _25_HOURS_AGO)
155 if not os.path.exists(core_path): 196 self._shift_file_mtime(unknown_file, _25_HOURS_AGO)
156 raise error.TestFail('Core file was removed') 197 results = self._call_sender_one_crash()
198 if (not 'Removing old orphaned file' in results['output'] or
199 os.path.exists(core_file) or os.path.exists(unknown_file)):
200 raise error.TestFail(
201 'Old orphaned files were not removed')
157 202
158 203
159 def _test_sender_unknown_report_kind(self): 204 def _test_sender_incomplete_metadata(self):
205 """Test that incomplete metadata file is removed once old."""
206 meta_file = self.write_crash_dir_entry('incomplete.meta', 'half=1')
207 dmp_file = self.write_crash_dir_entry('incomplete.dmp', '')
208 # As new files, we expect crash_sender to leave these alone.
160 self._set_sending(True) 209 self._set_sending(True)
161 bad_report = self.create_fake_crash_dir_entry('fake.bad') 210 results = self._call_sender_one_crash()
162 result = self._call_sender_one_crash(report=bad_report) 211 if ('Removing recent incomplete report' in results['output'] or
163 if (result['report_exists'] or 212 not os.path.exists(meta_file) or
164 result['rate_count'] != 0 or 213 not os.path.exists(dmp_file)):
165 result['send_attempt'] or 214 raise error.TestFail('New unknown files were removed')
166 result['send_success'] or 215 self._shift_file_mtime(meta_file, _25_HOURS_AGO)
167 not 'Unknown report' in result['output']): 216 results = self._call_sender_one_crash()
168 raise error.TestFail('Error handling of unknown report kind failed') 217 if (not 'Removing old incomplete metadata' in results['output'] or
218 os.path.exists(meta_file) or os.path.exists(dmp_file)):
219 raise error.TestFail(
220 'Old unknown/incomplete files were not removed')
169 221
170 222
171 def _test_cron_runs(self): 223 def _test_cron_runs(self):
172 """Test sender runs successfully as part of the hourly cron job. 224 """Test sender runs successfully as part of the hourly cron job.
173 225
174 Assuming we've run test_sender_simple which shows that a minidump 226 Assuming we've run test_sender_simple which shows that a minidump
175 gets removed as part of sending, we run the cron job (which is 227 gets removed as part of sending, we run the cron job (which is
176 asynchronous) and wait for that file to be removed to just verify 228 asynchronous) and wait for that file to be removed to just verify
177 the job eventually runs the sender.""" 229 the job eventually runs the sender."""
178 self._set_sending(True) 230 self._set_sending(True)
(...skipping 11 matching lines...) Expand all
190 crash_sender_log = self._log_reader.get_logs() 242 crash_sender_log = self._log_reader.get_logs()
191 logging.debug('Contents of crash sender log: ' + crash_sender_log) 243 logging.debug('Contents of crash sender log: ' + crash_sender_log)
192 result = self._parse_sender_output(crash_sender_log) 244 result = self._parse_sender_output(crash_sender_log)
193 if not result['send_attempt'] or not result['send_success']: 245 if not result['send_attempt'] or not result['send_success']:
194 raise error.TestFail('Cron simple run test failed') 246 raise error.TestFail('Cron simple run test failed')
195 247
196 248
197 def run_once(self): 249 def run_once(self):
198 self.run_crash_tests([ 250 self.run_crash_tests([
199 'sender_simple_minidump', 251 'sender_simple_minidump',
252 'sender_simple_old_minidump',
200 'sender_simple_kernel_crash', 253 'sender_simple_kernel_crash',
201 'sender_pausing', 254 'sender_pausing',
202 'sender_reports_disabled', 255 'sender_reports_disabled',
203 'sender_rate_limiting', 256 'sender_rate_limiting',
204 'sender_single_instance', 257 'sender_single_instance',
205 'sender_send_fails', 258 'sender_send_fails',
206 'sender_leaves_core_files', 259 'sender_orphaned_files',
207 'sender_unknown_report_kind', 260 'sender_incomplete_metadata',
208 'cron_runs']) 261 'cron_runs'])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698