blob: 4c6cc353de6d795047245378ce7556a13f0e5f63 [file] [log] [blame]
Ken Mixter20d9e472010-08-12 10:58:46 -07001# 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
3# found in the LICENSE file.
4
Dale Curtis497c2cb2010-11-16 13:44:33 -08005import logging, os, re, shutil
Eric Lie7c4cab2011-01-05 14:39:19 -08006import common
7import cros_logging
8from autotest_lib.client.bin import test, utils
9from autotest_lib.client.common_lib import error
Ken Mixter20d9e472010-08-12 10:58:46 -070010
11
12class CrashTest(test.test):
Simon Glassa47f0d72011-03-15 11:45:32 -070013 """
14 This class deals with running crash tests, which are tests which crash a
15 user-space program (or the whole machine) and generate a core dump. We
16 want to check that the correct crash dump is available and can be
17 retrieved.
18
19 Chromium OS has a crash sender which checks for new crash data and sends
20 it to a server. This crash data is used to track software quality and find
21 bugs. The system crash sender normally is always running, but can be paused
22 by creating _PAUSE_FILE. When crash sender sees this, it pauses operation.
23
24 The pid of the system crash sender is stored in _CRASH_SENDER_RUN_PATH so
25 we can use this to kill the system crash sender for when we want to run
26 our own.
27
28 For testing purposes we sometimes want to run the crash sender manually.
29 In this case we can set 'OVERRIDE_PAUSE_SENDING=1' in the environment and
30 run the crash sender manually (as a child process).
31
32 Also for testing we sometimes want to mock out the crash sender, and just
33 have it pretend to succeed or fail. The _MOCK_CRASH_SENDING file is used
34 for this. If it doesn't exist, then the crash sender runs normally. If
35 it exists but is empty, the crash sender will succeed (but actually do
36 nothing). If the file contains something, then the crash sender will fail.
37
38 If the user consents to sending crash tests, then the _CONSENT_FILE will
39 exist in the home directory. This test needs to create this file for the
40 crash sending to work.
41
42 Crash reports are rate limited to a certain number of reports each 24
43 hours. If the maximum number has already been sent then reports are held
44 until later. This is administered by a directory _CRASH_SENDER_RATE_DIR
45 which contains one temporary file for each time a report is sent.
46
47 The class provides the ability to push a consent file. This disables
48 consent for this test but allows it to be popped back at later. This
49 makes nested tests easier. If _automatic_consent_saving is True (the
50 default) then consent will be pushed at the start and popped at the end.
51
52 Interesting variables:
53 _log_reader: the log reader used for reading log files
54 _leave_crash_sending: True to enable crash sending on exit from the
55 test, False to disable it. (Default True).
56 _automatic_consent_saving: True to push the consent at the start of
57 the test and pop it afterwards. (Default True).
58
59 Useful places to look for more information are:
60
61 chromeos/src/platform/crash-reporter/crash_sender
62 - sender script which crash crash reporter to create reports, then
63
64 chromeos/src/platform/crash-reporter/
65 - crash reporter program
66 """
67
Ken Mixter20d9e472010-08-12 10:58:46 -070068
69 _CONSENT_FILE = '/home/chronos/Consent To Send Stats'
Ken Mixterddcd92d2010-11-01 19:07:08 -070070 _CORE_PATTERN = '/proc/sys/kernel/core_pattern'
Ken Mixter20d9e472010-08-12 10:58:46 -070071 _CRASH_REPORTER_PATH = '/sbin/crash_reporter'
72 _CRASH_SENDER_PATH = '/sbin/crash_sender'
73 _CRASH_SENDER_RATE_DIR = '/var/lib/crash_sender'
74 _CRASH_SENDER_RUN_PATH = '/var/run/crash_sender.pid'
Thieu Lec16253b2011-03-03 11:13:54 -080075 _CRASH_TEST_IN_PROGRESS = '/tmp/crash-test-in-progress'
Ken Mixter20d9e472010-08-12 10:58:46 -070076 _MOCK_CRASH_SENDING = '/tmp/mock-crash-sending'
Ken Mixter38dfe852010-08-18 15:24:00 -070077 _PAUSE_FILE = '/var/lib/crash_sender_paused'
Ken Mixter20d9e472010-08-12 10:58:46 -070078 _SYSTEM_CRASH_DIR = '/var/spool/crash'
79 _USER_CRASH_DIR = '/home/chronos/user/crash'
80
Ken Mixter4f619652010-10-18 12:11:18 -070081 def _set_system_sending(self, is_enabled):
82 """Sets whether or not the system crash_sender is allowed to run.
83
Simon Glassa47f0d72011-03-15 11:45:32 -070084 This is done by creating or removing _PAUSE_FILE.
85
Ken Mixter4f619652010-10-18 12:11:18 -070086 crash_sender may still be allowed to run if _set_child_sending is
Simon Glassa47f0d72011-03-15 11:45:32 -070087 called with True and it is run as a child process.
88
89 Args:
90 is_enabled: True to enable crash_sender, False to disable it.
91 """
Ken Mixter20d9e472010-08-12 10:58:46 -070092 if is_enabled:
93 if os.path.exists(self._PAUSE_FILE):
94 os.remove(self._PAUSE_FILE)
95 else:
96 utils.system('touch ' + self._PAUSE_FILE)
97
98
Ken Mixter4f619652010-10-18 12:11:18 -070099 def _set_child_sending(self, is_enabled):
Simon Glassa47f0d72011-03-15 11:45:32 -0700100 """Overrides crash sending enabling for child processes.
101
102 When the system crash sender is disabled this test can manually run
103 the crash sender as a child process. Normally this would do nothing,
104 but this function sets up crash_sender to ignore its disabled status
105 and do its job.
106
107 Args:
108 is_enabled: True to enable crash sending for child processes.
109 """
Ken Mixter4f619652010-10-18 12:11:18 -0700110 if is_enabled:
111 os.environ['OVERRIDE_PAUSE_SENDING'] = "1"
112 else:
113 del os.environ['OVERRIDE_PAUSE_SENDING']
114
115
Ken Mixter20d9e472010-08-12 10:58:46 -0700116 def _reset_rate_limiting(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700117 """Reset the count of crash reports sent today.
118
119 This clears the contents of the rate limiting directory which has
120 the effect of reseting our count of crash reports sent.
121 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700122 utils.system('rm -rf ' + self._CRASH_SENDER_RATE_DIR)
123
124
125 def _clear_spooled_crashes(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700126 """Clears system and user crash directories.
127
128 This will remove all crash reports which are waiting to be sent.
129 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700130 utils.system('rm -rf ' + self._SYSTEM_CRASH_DIR)
131 utils.system('rm -rf ' + self._USER_CRASH_DIR)
132
133
134 def _kill_running_sender(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700135 """Kill the the crash_sender process if running.
136
137 We use the PID file to find the process ID, then kill it with signal 9.
138 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700139 if not os.path.exists(self._CRASH_SENDER_RUN_PATH):
140 return
141 running_pid = int(utils.read_file(self._CRASH_SENDER_RUN_PATH))
142 logging.warning('Detected running crash sender (%d), killing' %
143 running_pid)
144 utils.system('kill -9 %d' % running_pid)
145 os.remove(self._CRASH_SENDER_RUN_PATH)
146
147
148 def _set_sending_mock(self, mock_enabled, send_success=True):
Simon Glassa47f0d72011-03-15 11:45:32 -0700149 """Enables / disables mocking of the sending process.
150
151 This uses the _MOCK_CRASH_SENDING file to achieve its aims. See notes
152 at the top.
153
154 Args:
155 mock_enabled: If True, mocking is enabled, else it is disabled.
156 send_success: If mock_enabled this is True for the mocking to
157 indicate success, False to indicate failure.
158 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700159 if mock_enabled:
160 if send_success:
161 data = ''
162 else:
163 data = '1'
164 logging.info('Setting sending mock')
165 utils.open_write_close(self._MOCK_CRASH_SENDING, data)
166 else:
167 utils.system('rm -f ' + self._MOCK_CRASH_SENDING)
168
169
170 def _set_consent(self, has_consent):
Simon Glassa47f0d72011-03-15 11:45:32 -0700171 """Sets whether or not we have consent to send crash reports.
172
173 This creates or deletes the _CONSENT_FILE to control whether
174 crash_sender will consider that it has consent to send crash reports.
175
176 Args:
177 has_consent: True to indicate consent, False otherwise
178 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700179 if has_consent:
180 utils.open_write_close(self._CONSENT_FILE, 'test-consent')
Michael Krebs05400be2011-06-27 17:14:56 -0700181 utils.system('chown chronos:chronos "%s"' % (self._CONSENT_FILE))
Ken Mixter20d9e472010-08-12 10:58:46 -0700182 logging.info('Created ' + self._CONSENT_FILE)
183 else:
184 utils.system('rm -f "%s"' % (self._CONSENT_FILE))
185
186
Thieu Lec16253b2011-03-03 11:13:54 -0800187 def _set_crash_test_in_progress(self, in_progress):
188 if in_progress:
189 utils.open_write_close(self._CRASH_TEST_IN_PROGRESS, 'in-progress')
190 logging.info('Created ' + self._CRASH_TEST_IN_PROGRESS)
191 else:
192 utils.system('rm -f "%s"' % (self._CRASH_TEST_IN_PROGRESS))
193
194
Ken Mixter20d9e472010-08-12 10:58:46 -0700195 def _get_pushed_consent_file_path(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700196 """Returns filename of the pushed consent file."""
Ken Mixter20d9e472010-08-12 10:58:46 -0700197 return os.path.join(self.bindir, 'pushed_consent')
198
199
200 def _push_consent(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700201 """Push the consent file, thus disabling consent.
202
203 The consent file can be created in the new test if required. Call
204 _pop_consent() to restore the original state.
205 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700206 if os.path.exists(self._CONSENT_FILE):
Dale Curtis497c2cb2010-11-16 13:44:33 -0800207 shutil.move(self._CONSENT_FILE,
208 self._get_pushed_consent_file_path())
Ken Mixter20d9e472010-08-12 10:58:46 -0700209
210
211 def _pop_consent(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700212 """Pop the consent file, enabling/disabling consent as it was before
213 we pushed the consent."""
Ken Mixter20d9e472010-08-12 10:58:46 -0700214 self._set_consent(False)
215 if os.path.exists(self._get_pushed_consent_file_path()):
Dale Curtis497c2cb2010-11-16 13:44:33 -0800216 shutil.move(self._get_pushed_consent_file_path(),
217 self._CONSENT_FILE)
Ken Mixter20d9e472010-08-12 10:58:46 -0700218
219
220 def _get_crash_dir(self, username):
Simon Glassa47f0d72011-03-15 11:45:32 -0700221 """Returns full path to the crash directory for a given username
222
223 Args:
224 username: username to use:
225 'chronos': Returns user crash directory.
226 'root': Returns system crash directory.
227 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700228 if username == 'chronos':
229 return self._USER_CRASH_DIR
230 else:
231 return self._SYSTEM_CRASH_DIR
232
233
234 def _initialize_crash_reporter(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700235 """Start up the crash reporter."""
Ken Mixter20d9e472010-08-12 10:58:46 -0700236 utils.system('%s --init --nounclean_check' % self._CRASH_REPORTER_PATH)
Ken Mixterddcd92d2010-11-01 19:07:08 -0700237 # Completely disable crash_reporter from generating crash dumps
238 # while any tests are running, otherwise a crashy system can make
239 # these tests flaky.
240 self.enable_crash_filtering('none')
Ken Mixter20d9e472010-08-12 10:58:46 -0700241
242
Ken Mixter67ff5622010-09-30 15:32:17 -0700243 def write_crash_dir_entry(self, name, contents):
Simon Glassa47f0d72011-03-15 11:45:32 -0700244 """Writes an empty file to the system crash directory.
245
246 This writes a file to _SYSTEM_CRASH_DIR with the given name. This is
247 used to insert new crash dump files for testing purposes.
248
249 Args:
250 name: Name of file to write.
251 contents: String to write to the file.
252 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700253 entry = os.path.join(self._SYSTEM_CRASH_DIR, name)
254 if not os.path.exists(self._SYSTEM_CRASH_DIR):
255 os.makedirs(self._SYSTEM_CRASH_DIR)
Ken Mixter67ff5622010-09-30 15:32:17 -0700256 utils.open_write_close(entry, contents)
Ken Mixter20d9e472010-08-12 10:58:46 -0700257 return entry
258
259
Ken Mixterdee4e292010-12-14 17:45:21 -0800260 def write_fake_meta(self, name, exec_name, payload, log=None,
261 complete=True):
Simon Glassa47f0d72011-03-15 11:45:32 -0700262 """Writes a fake meta entry to the system crash directory.
263
264 Args:
265 name: Name of file to write.
266 exec_name: Value for exec_name item.
267 payload: Value for payload item.
268 log: Value for log item.
269 complete: True to close off the record, otherwise leave it
270 incomplete.
271 """
Ken Mixter1a894e02010-10-28 15:42:52 -0700272 last_line = ''
273 if complete:
274 last_line = 'done=1\n'
Ken Mixterdee4e292010-12-14 17:45:21 -0800275 contents = ('exec_name=%s\n'
276 'ver=my_ver\n'
277 'payload=%s\n'
278 '%s' % (exec_name, payload,
279 last_line))
280 if log:
281 contents = ('log=%s\n' % log) + contents
282 return self.write_crash_dir_entry(name, contents)
Ken Mixter67ff5622010-09-30 15:32:17 -0700283
284
Ken Mixter20d9e472010-08-12 10:58:46 -0700285 def _prepare_sender_one_crash(self,
286 send_success,
287 reports_enabled,
Ken Mixter38dfe852010-08-18 15:24:00 -0700288 report):
Simon Glassa47f0d72011-03-15 11:45:32 -0700289 """Create metadata for a fake crash report.
290
291 This enabled mocking of the crash sender, then creates a fake
292 crash report for testing purposes.
293
294 Args:
295 send_success: True to make the crash_sender success, False to make
296 it fail.
297 reports_enabled: True to enable consent to that reports will be
298 sent.
299 report: Report to use for crash, if None we create one.
300 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700301 self._set_sending_mock(mock_enabled=True, send_success=send_success)
302 self._set_consent(reports_enabled)
Ken Mixter38dfe852010-08-18 15:24:00 -0700303 if report is None:
Ken Mixter1a894e02010-10-28 15:42:52 -0700304 payload = self.write_crash_dir_entry('fake.dmp', '')
305 report = self.write_fake_meta('fake.meta', 'fake', payload)
Ken Mixter38dfe852010-08-18 15:24:00 -0700306 return report
Ken Mixter20d9e472010-08-12 10:58:46 -0700307
308
309 def _parse_sender_output(self, output):
310 """Parse the log output from the crash_sender script.
311
312 This script can run on the logs from either a mocked or true
313 crash send.
314
315 Args:
316 output: output from the script
317
318 Returns:
319 A dictionary with these values:
Ken Mixter38dfe852010-08-18 15:24:00 -0700320 exec_name: name of executable which crashed
Ken Mixter67ff5622010-09-30 15:32:17 -0700321 meta_path: path to the report metadata file
322 output: the output from the script, copied
Ken Mixter38dfe852010-08-18 15:24:00 -0700323 report_kind: kind of report sent (minidump vs kernel)
Ken Mixter20d9e472010-08-12 10:58:46 -0700324 send_attempt: did the script attempt to send a crash.
325 send_success: if it attempted, was the crash send successful.
Ken Mixterd79140e2010-10-26 14:45:30 -0700326 sig: signature of the report, if given.
Ken Mixter20d9e472010-08-12 10:58:46 -0700327 sleep_time: if it attempted, how long did it sleep before
328 sending (if mocked, how long would it have slept)
Ken Mixter20d9e472010-08-12 10:58:46 -0700329 """
330 sleep_match = re.search('Scheduled to send in (\d+)s', output)
331 send_attempt = sleep_match is not None
332 if send_attempt:
333 sleep_time = int(sleep_match.group(1))
334 else:
335 sleep_time = None
Ken Mixter67ff5622010-09-30 15:32:17 -0700336 meta_match = re.search('Metadata: (\S+) \((\S+)\)', output)
337 if meta_match:
338 meta_path = meta_match.group(1)
339 report_kind = meta_match.group(2)
Ken Mixter38dfe852010-08-18 15:24:00 -0700340 else:
Ken Mixter67ff5622010-09-30 15:32:17 -0700341 meta_path = None
Ken Mixter38dfe852010-08-18 15:24:00 -0700342 report_kind = None
Ken Mixter67ff5622010-09-30 15:32:17 -0700343 payload_match = re.search('Payload: (\S+)', output)
344 if payload_match:
345 report_payload = payload_match.group(1)
346 else:
347 report_payload = None
Ken Mixter38dfe852010-08-18 15:24:00 -0700348 exec_name_match = re.search('Exec name: (\S+)', output)
349 if exec_name_match:
350 exec_name = exec_name_match.group(1)
351 else:
352 exec_name = None
Ken Mixter10c48672010-11-01 13:37:08 -0700353 sig_match = re.search('sig: (\S+)', output)
Ken Mixterd79140e2010-10-26 14:45:30 -0700354 if sig_match:
355 sig = sig_match.group(1)
356 else:
357 sig = None
Ken Mixter20d9e472010-08-12 10:58:46 -0700358 send_success = 'Mocking successful send' in output
Ken Mixter38dfe852010-08-18 15:24:00 -0700359 return {'exec_name': exec_name,
360 'report_kind': report_kind,
Ken Mixter67ff5622010-09-30 15:32:17 -0700361 'meta_path': meta_path,
362 'report_payload': report_payload,
Ken Mixter38dfe852010-08-18 15:24:00 -0700363 'send_attempt': send_attempt,
Ken Mixter20d9e472010-08-12 10:58:46 -0700364 'send_success': send_success,
Ken Mixterd79140e2010-10-26 14:45:30 -0700365 'sig': sig,
Ken Mixter20d9e472010-08-12 10:58:46 -0700366 'sleep_time': sleep_time,
367 'output': output}
368
369
Ken Mixter654f32e2010-10-20 11:47:31 -0700370 def wait_for_sender_completion(self):
371 """Wait for crash_sender to complete.
372
373 Wait for no crash_sender's last message to be placed in the
374 system log before continuing and for the process to finish.
375 Otherwise we might get only part of the output."""
Eric Lie7c4cab2011-01-05 14:39:19 -0800376 utils.poll_for_condition(
Ken Mixter654f32e2010-10-20 11:47:31 -0700377 lambda: self._log_reader.can_find('crash_sender done.'),
378 timeout=60,
379 exception=error.TestError(
380 'Timeout waiting for crash_sender to emit done: ' +
381 self._log_reader.get_logs()))
Eric Lie7c4cab2011-01-05 14:39:19 -0800382 utils.poll_for_condition(
Ken Mixter654f32e2010-10-20 11:47:31 -0700383 lambda: utils.system('pgrep crash_sender',
384 ignore_status=True) != 0,
385 timeout=60,
386 exception=error.TestError(
387 'Timeout waiting for crash_sender to finish: ' +
388 self._log_reader.get_logs()))
389
390
Ken Mixter20d9e472010-08-12 10:58:46 -0700391 def _call_sender_one_crash(self,
392 send_success=True,
393 reports_enabled=True,
394 username='root',
Ken Mixter38dfe852010-08-18 15:24:00 -0700395 report=None):
Ken Mixter20d9e472010-08-12 10:58:46 -0700396 """Call the crash sender script to mock upload one crash.
397
398 Args:
399 send_success: Mock a successful send if true
400 reports_enabled: Has the user consented to sending crash reports.
401 username: user to emulate a crash from
Ken Mixter38dfe852010-08-18 15:24:00 -0700402 report: report to use for crash, if None we create one.
Ken Mixter20d9e472010-08-12 10:58:46 -0700403
404 Returns:
405 Returns a dictionary describing the result with the keys
406 from _parse_sender_output, as well as:
Ken Mixter38dfe852010-08-18 15:24:00 -0700407 report_exists: does the minidump still exist after calling
Ken Mixter20d9e472010-08-12 10:58:46 -0700408 send script
409 rate_count: how many crashes have been uploaded in the past
410 24 hours.
411 """
Ken Mixter38dfe852010-08-18 15:24:00 -0700412 report = self._prepare_sender_one_crash(send_success,
413 reports_enabled,
Ken Mixter38dfe852010-08-18 15:24:00 -0700414 report)
Ken Mixter20d9e472010-08-12 10:58:46 -0700415 self._log_reader.set_start_by_current()
416 script_output = utils.system_output(
417 '/bin/sh -c "%s" 2>&1' % self._CRASH_SENDER_PATH,
418 ignore_status=True)
Ken Mixter654f32e2010-10-20 11:47:31 -0700419 self.wait_for_sender_completion()
Ken Mixter20d9e472010-08-12 10:58:46 -0700420 output = self._log_reader.get_logs()
421 logging.debug('Crash sender message output:\n' + output)
422 if script_output != '':
423 raise error.TestFail(
424 'Unexpected crash_sender stdout/stderr: ' + script_output)
425
Ken Mixter38dfe852010-08-18 15:24:00 -0700426 if os.path.exists(report):
427 report_exists = True
428 os.remove(report)
Ken Mixter20d9e472010-08-12 10:58:46 -0700429 else:
Ken Mixter38dfe852010-08-18 15:24:00 -0700430 report_exists = False
Ken Mixter20d9e472010-08-12 10:58:46 -0700431 if os.path.exists(self._CRASH_SENDER_RATE_DIR):
432 rate_count = len(os.listdir(self._CRASH_SENDER_RATE_DIR))
433 else:
434 rate_count = 0
435
436 result = self._parse_sender_output(output)
Ken Mixter38dfe852010-08-18 15:24:00 -0700437 result['report_exists'] = report_exists
Ken Mixter20d9e472010-08-12 10:58:46 -0700438 result['rate_count'] = rate_count
439
440 # Show the result for debugging but remove 'output' key
441 # since it's large and earlier in debug output.
442 debug_result = dict(result)
443 del debug_result['output']
444 logging.debug('Result of send (besides output): %s' % debug_result)
445
446 return result
447
448
Ken Mixterddcd92d2010-11-01 19:07:08 -0700449 def _replace_crash_reporter_filter_in(self, new_parameter):
Simon Glassa47f0d72011-03-15 11:45:32 -0700450 """Replaces the --filter_in= parameter of the crash reporter.
451
452 The kernel is set up to call the crash reporter with the core dump
453 as stdin when a process dies. This function adds a filter to the
454 command line used to call the crash reporter. This is used to ignore
455 crashes in which we have no interest.
456
457 This removes any --filter_in= parameter and optionally replaces it
458 with a new one.
459
460 Args:
461 new_parameter: This is parameter to add to the command line
462 instead of the --filter_in=... that was there.
463 """
Ken Mixterddcd92d2010-11-01 19:07:08 -0700464 core_pattern = utils.read_file(self._CORE_PATTERN)[:-1]
465 core_pattern = re.sub('--filter_in=\S*\s*', '',
466 core_pattern).rstrip()
467 if new_parameter:
468 core_pattern += ' ' + new_parameter
469 utils.system('echo "%s" > %s' % (core_pattern, self._CORE_PATTERN))
470
471
472 def enable_crash_filtering(self, name):
Simon Glassa47f0d72011-03-15 11:45:32 -0700473 """Add a --filter_in argument to the kernel core dump cmdline.
474
475 Args:
476 name: Filter text to use. This is passed as a --filter_in
477 argument to the crash reporter.
478 """
Ken Mixterddcd92d2010-11-01 19:07:08 -0700479 self._replace_crash_reporter_filter_in('--filter_in=' + name)
480
481
482 def disable_crash_filtering(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700483 """Remove the --filter_in argument from the kernel core dump cmdline.
484
485 Next time the crash reporter is invoked (due to a crash) it will not
486 receive a --filter_in paramter."""
Ken Mixterddcd92d2010-11-01 19:07:08 -0700487 self._replace_crash_reporter_filter_in('')
488
489
Ken Mixter20d9e472010-08-12 10:58:46 -0700490 def initialize(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700491 """Initalize the test."""
Ken Mixter20d9e472010-08-12 10:58:46 -0700492 test.test.initialize(self)
Eric Lie7c4cab2011-01-05 14:39:19 -0800493 self._log_reader = cros_logging.LogReader()
Ken Mixter38dfe852010-08-18 15:24:00 -0700494 self._leave_crash_sending = True
Ken Mixter67ff5622010-09-30 15:32:17 -0700495 self._automatic_consent_saving = True
Ken Mixterddcd92d2010-11-01 19:07:08 -0700496 self.enable_crash_filtering('none')
Thieu Lec16253b2011-03-03 11:13:54 -0800497 self._set_crash_test_in_progress(True)
Ken Mixter20d9e472010-08-12 10:58:46 -0700498
499
500 def cleanup(self):
Simon Glassa47f0d72011-03-15 11:45:32 -0700501 """Cleanup after the test.
502
503 We reset things back to the way we think they should be. This is
504 intended to allow the system to continue normal operation.
505
506 Some variables silently change the behavior:
507 _automatic_consent_saving: if True, we pop the consent file.
508 _leave_crash_sending: True to enable crash sending, False to
509 disable it
510 """
Ken Mixter20d9e472010-08-12 10:58:46 -0700511 self._reset_rate_limiting()
512 self._clear_spooled_crashes()
Ken Mixter4f619652010-10-18 12:11:18 -0700513 self._set_system_sending(self._leave_crash_sending)
Ken Mixter20d9e472010-08-12 10:58:46 -0700514 self._set_sending_mock(mock_enabled=False)
Ken Mixter67ff5622010-09-30 15:32:17 -0700515 if self._automatic_consent_saving:
516 self._pop_consent()
Ken Mixterddcd92d2010-11-01 19:07:08 -0700517 self.disable_crash_filtering()
Thieu Lec16253b2011-03-03 11:13:54 -0800518 self._set_crash_test_in_progress(False)
Ken Mixter20d9e472010-08-12 10:58:46 -0700519 test.test.cleanup(self)
520
521
Ken Mixter38dfe852010-08-18 15:24:00 -0700522 def run_crash_tests(self,
523 test_names,
524 initialize_crash_reporter=False,
525 clear_spool_first=True,
526 must_run_all=True):
527 """Run crash tests defined in this class.
528
529 Args:
Simon Glassa47f0d72011-03-15 11:45:32 -0700530 test_names: Array of test names.
531 initialize_crash_reporter: Should set up crash reporter for every
532 run.
533 clear_spool_first: Clear all spooled user/system crashes before
534 starting the test.
535 must_run_all: Should make sure every test in this class is
536 mentioned in test_names.
Ken Mixter38dfe852010-08-18 15:24:00 -0700537 """
Ken Mixter67ff5622010-09-30 15:32:17 -0700538 if self._automatic_consent_saving:
539 self._push_consent()
Ken Mixter20d9e472010-08-12 10:58:46 -0700540
Ken Mixter38dfe852010-08-18 15:24:00 -0700541 if must_run_all:
542 # Sanity check test_names is complete
543 for attr in dir(self):
544 if attr.find('_test_') == 0:
545 test_name = attr[6:]
546 if not test_name in test_names:
547 raise error.TestError('Test %s is missing' % test_name)
Ken Mixter20d9e472010-08-12 10:58:46 -0700548
549 for test_name in test_names:
550 logging.info(('=' * 20) + ('Running %s' % test_name) + ('=' * 20))
Ken Mixter38dfe852010-08-18 15:24:00 -0700551 if initialize_crash_reporter:
552 self._initialize_crash_reporter()
Ken Mixter4f619652010-10-18 12:11:18 -0700553 # Disable crash_sender from running, kill off any running ones, but
554 # set environment so crash_sender may run as a child process.
555 self._set_system_sending(False)
556 self._set_child_sending(True)
Ken Mixter20d9e472010-08-12 10:58:46 -0700557 self._kill_running_sender()
558 self._reset_rate_limiting()
Ken Mixter38dfe852010-08-18 15:24:00 -0700559 if clear_spool_first:
560 self._clear_spooled_crashes()
Simon Glassa47f0d72011-03-15 11:45:32 -0700561
562 # Call the test function
Ken Mixter20d9e472010-08-12 10:58:46 -0700563 getattr(self, '_test_' + test_name)()