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 logging, os, re, shutil | 5 import logging, os, re, shutil |
6 import common | 6 import common |
7 import cros_logging | 7 import cros_logging |
8 from autotest_lib.client.bin import test, utils | 8 from autotest_lib.client.bin import test, utils |
9 from autotest_lib.client.common_lib import error | 9 from autotest_lib.client.common_lib import error |
10 | 10 |
11 | 11 |
12 class CrashTest(test.test): | 12 class CrashTest(test.test): |
13 """ | |
14 This class deals with running crash tests, which are tests which crash the | |
15 machine and generate a core dump. We want to check that the correct crash | |
kmixter1
2011/02/25 00:15:15
Not necessarily the whole machine - both kernel or
| |
16 dump is available and can be retrieved. | |
17 | |
18 Chromium OS has a crash sender which checks for new crash data and sends | |
19 it to a server. This crash data is used to track software quality and find | |
20 bugs. The system crash sender normally is always running, but can be paused | |
21 by creating _PAUSE_FILE. When crash sender sees this, it pauses operation. | |
22 | |
23 The pid of the system crash sender is stored in _CRASH_SENDER_RUN_PATH so | |
24 we can use this to kill the system crash sender for when we want to run | |
25 our own. | |
26 | |
27 For testing purposes we sometimes want to run the crash sender manually. | |
28 In this case we can set 'OVERRIDE_PAUSE_SENDING=1' in the environment and | |
29 run the crash sender manually (as a child process). | |
30 | |
31 Also for testing we sometimes want to mock out the crash sender, and just | |
32 have it pretend to succeed or fail. The _MOCK_CRASH_SENDING file is used | |
33 for this. If it doesn't exist, then the crash sender runs normally. If | |
34 it exists but is empty, the crash sender will succeed (but actually do | |
35 nothing). If the file contains something, then the crash sender will fail. | |
36 | |
37 If the user consents to sending crash tests, then the _CONSENT_FILE will | |
38 exist in the home directory. This test needs to create this file for the | |
39 crash sending to work. | |
40 | |
41 Crash reports are rate limited to a certain number of reports each 24 | |
42 hours. If the maximum number has already been sent then reports are held | |
43 until later. This is administered by a directory _CRASH_SENDER_RATE_DIR | |
44 which contains one temporary file for each time a report is sent. | |
45 | |
46 The class provides the ability to push a consent file. This disables | |
47 consent for this test but allows it to be popped back at later. This | |
48 makes nested tests easier. If _automatic_consent_saving is True (the | |
49 default) then consent will be pushed at the start and popped at the end. | |
50 | |
51 Interesting variables: | |
52 _log_reader: the log reader used for reading log files | |
53 _leave_crash_sending: True to enable crash sending on exit from the | |
54 test, False to disable it. (Default True). | |
55 _automatic_consent_saving: True to push the consent at the start of | |
56 the test and pop it afterwards. (Default True). | |
57 | |
58 Useful places to look for more information are: | |
59 | |
60 chromeos/src/platform/crash-reporter/crash_sender | |
61 - sender script which crash crash reporter to create reports, then | |
62 | |
63 chromeos/src/platform/crash-reporter/ | |
64 - crash reporter program | |
65 """ | |
66 | |
13 | 67 |
14 _CONSENT_FILE = '/home/chronos/Consent To Send Stats' | 68 _CONSENT_FILE = '/home/chronos/Consent To Send Stats' |
15 _CORE_PATTERN = '/proc/sys/kernel/core_pattern' | 69 _CORE_PATTERN = '/proc/sys/kernel/core_pattern' |
16 _CRASH_REPORTER_PATH = '/sbin/crash_reporter' | 70 _CRASH_REPORTER_PATH = '/sbin/crash_reporter' |
17 _CRASH_SENDER_PATH = '/sbin/crash_sender' | 71 _CRASH_SENDER_PATH = '/sbin/crash_sender' |
18 _CRASH_SENDER_RATE_DIR = '/var/lib/crash_sender' | 72 _CRASH_SENDER_RATE_DIR = '/var/lib/crash_sender' |
19 _CRASH_SENDER_RUN_PATH = '/var/run/crash_sender.pid' | 73 _CRASH_SENDER_RUN_PATH = '/var/run/crash_sender.pid' |
20 _MOCK_CRASH_SENDING = '/tmp/mock-crash-sending' | 74 _MOCK_CRASH_SENDING = '/tmp/mock-crash-sending' |
21 _PAUSE_FILE = '/var/lib/crash_sender_paused' | 75 _PAUSE_FILE = '/var/lib/crash_sender_paused' |
22 _SYSTEM_CRASH_DIR = '/var/spool/crash' | 76 _SYSTEM_CRASH_DIR = '/var/spool/crash' |
23 _USER_CRASH_DIR = '/home/chronos/user/crash' | 77 _USER_CRASH_DIR = '/home/chronos/user/crash' |
24 | 78 |
25 def _set_system_sending(self, is_enabled): | 79 def _set_system_sending(self, is_enabled): |
26 """Sets whether or not the system crash_sender is allowed to run. | 80 """Sets whether or not the system crash_sender is allowed to run. |
27 | 81 |
82 This is done by creating or removing _PAUSE_FILE. | |
83 | |
28 crash_sender may still be allowed to run if _set_child_sending is | 84 crash_sender may still be allowed to run if _set_child_sending is |
29 called with true and it is run as a child process.""" | 85 called with True and it is run as a child process. |
86 | |
87 Args: | |
88 is_enabled: True to enable crash_sender, False to disable it. | |
89 """ | |
30 if is_enabled: | 90 if is_enabled: |
31 if os.path.exists(self._PAUSE_FILE): | 91 if os.path.exists(self._PAUSE_FILE): |
32 os.remove(self._PAUSE_FILE) | 92 os.remove(self._PAUSE_FILE) |
33 else: | 93 else: |
34 utils.system('touch ' + self._PAUSE_FILE) | 94 utils.system('touch ' + self._PAUSE_FILE) |
35 | 95 |
36 | 96 |
37 def _set_child_sending(self, is_enabled): | 97 def _set_child_sending(self, is_enabled): |
38 """Overrides crash sending enabling for child processes.""" | 98 """Overrides crash sending enabling for child processes. |
99 | |
100 When the system crash sender is disabled this test can manually run | |
101 the crash sender as a child process. Normally this would do nothing, | |
102 but this function sets up crash_sender to ignore its disabled status | |
103 and do its job. | |
104 | |
105 Args: | |
106 is_enabled: True to enable crash sending for child processes. | |
107 """ | |
39 if is_enabled: | 108 if is_enabled: |
40 os.environ['OVERRIDE_PAUSE_SENDING'] = "1" | 109 os.environ['OVERRIDE_PAUSE_SENDING'] = "1" |
41 else: | 110 else: |
42 del os.environ['OVERRIDE_PAUSE_SENDING'] | 111 del os.environ['OVERRIDE_PAUSE_SENDING'] |
43 | 112 |
44 | 113 |
45 def _reset_rate_limiting(self): | 114 def _reset_rate_limiting(self): |
115 """Reset the count of crash reports sent today. | |
116 | |
117 This clears the contents of the rate limiting directory which has | |
118 the effect of reseting our count of crash reports sent. | |
119 """ | |
46 utils.system('rm -rf ' + self._CRASH_SENDER_RATE_DIR) | 120 utils.system('rm -rf ' + self._CRASH_SENDER_RATE_DIR) |
47 | 121 |
48 | 122 |
49 def _clear_spooled_crashes(self): | 123 def _clear_spooled_crashes(self): |
124 """Clears system and user crash directories. | |
125 | |
126 This will remove all crash reports which are waiting to be sent. | |
127 """ | |
50 utils.system('rm -rf ' + self._SYSTEM_CRASH_DIR) | 128 utils.system('rm -rf ' + self._SYSTEM_CRASH_DIR) |
51 utils.system('rm -rf ' + self._USER_CRASH_DIR) | 129 utils.system('rm -rf ' + self._USER_CRASH_DIR) |
52 | 130 |
53 | 131 |
54 def _kill_running_sender(self): | 132 def _kill_running_sender(self): |
133 """Kill the the crash_sender process if running. | |
134 | |
135 We use the PID file to find the process ID, then kill it with signal 9. | |
136 """ | |
55 if not os.path.exists(self._CRASH_SENDER_RUN_PATH): | 137 if not os.path.exists(self._CRASH_SENDER_RUN_PATH): |
56 return | 138 return |
57 running_pid = int(utils.read_file(self._CRASH_SENDER_RUN_PATH)) | 139 running_pid = int(utils.read_file(self._CRASH_SENDER_RUN_PATH)) |
58 logging.warning('Detected running crash sender (%d), killing' % | 140 logging.warning('Detected running crash sender (%d), killing' % |
59 running_pid) | 141 running_pid) |
60 utils.system('kill -9 %d' % running_pid) | 142 utils.system('kill -9 %d' % running_pid) |
61 os.remove(self._CRASH_SENDER_RUN_PATH) | 143 os.remove(self._CRASH_SENDER_RUN_PATH) |
62 | 144 |
63 | 145 |
64 def _set_sending_mock(self, mock_enabled, send_success=True): | 146 def _set_sending_mock(self, mock_enabled, send_success=True): |
147 """Enables / disables mocking of the sending process. | |
148 | |
149 This uses the _MOCK_CRASH_SENDING file to achieve its aims. See notes | |
150 at the top. | |
151 | |
152 Args: | |
153 mock_enabled: If True, mocking is enabled, else it is disabled. | |
154 send_success: If mock_enabled this is True for the mocking to | |
155 indicate success, False to indicate failure. | |
156 """ | |
65 if mock_enabled: | 157 if mock_enabled: |
66 if send_success: | 158 if send_success: |
67 data = '' | 159 data = '' |
68 else: | 160 else: |
69 data = '1' | 161 data = '1' |
70 logging.info('Setting sending mock') | 162 logging.info('Setting sending mock') |
71 utils.open_write_close(self._MOCK_CRASH_SENDING, data) | 163 utils.open_write_close(self._MOCK_CRASH_SENDING, data) |
72 else: | 164 else: |
73 utils.system('rm -f ' + self._MOCK_CRASH_SENDING) | 165 utils.system('rm -f ' + self._MOCK_CRASH_SENDING) |
74 | 166 |
75 | 167 |
76 def _set_consent(self, has_consent): | 168 def _set_consent(self, has_consent): |
169 """Sets whether or not we have consent to send crash reports. | |
170 | |
171 This creates or deletes the _CONSENT_FILE to control whether | |
172 crash_sender will consider that it has consent to send crash reports. | |
173 | |
174 Args: | |
175 has_consent: True to indicate consent, False otherwise | |
176 """ | |
77 if has_consent: | 177 if has_consent: |
78 utils.open_write_close(self._CONSENT_FILE, 'test-consent') | 178 utils.open_write_close(self._CONSENT_FILE, 'test-consent') |
79 logging.info('Created ' + self._CONSENT_FILE) | 179 logging.info('Created ' + self._CONSENT_FILE) |
80 else: | 180 else: |
81 utils.system('rm -f "%s"' % (self._CONSENT_FILE)) | 181 utils.system('rm -f "%s"' % (self._CONSENT_FILE)) |
82 | 182 |
83 | 183 |
84 def _get_pushed_consent_file_path(self): | 184 def _get_pushed_consent_file_path(self): |
185 """Returns filename of the pushed consent file.""" | |
85 return os.path.join(self.bindir, 'pushed_consent') | 186 return os.path.join(self.bindir, 'pushed_consent') |
86 | 187 |
87 | 188 |
88 def _push_consent(self): | 189 def _push_consent(self): |
190 """Push the consent file, thus disabling consent. | |
191 | |
192 The consent file can be created in the new test if required. Call | |
193 _pop_consent() to restore the original state. | |
194 """ | |
89 if os.path.exists(self._CONSENT_FILE): | 195 if os.path.exists(self._CONSENT_FILE): |
90 shutil.move(self._CONSENT_FILE, | 196 shutil.move(self._CONSENT_FILE, |
91 self._get_pushed_consent_file_path()) | 197 self._get_pushed_consent_file_path()) |
92 | 198 |
93 | 199 |
94 def _pop_consent(self): | 200 def _pop_consent(self): |
201 """Pop the consent file, enabling/disabling consent as it was before | |
202 we pushed the consent.""" | |
95 self._set_consent(False) | 203 self._set_consent(False) |
96 if os.path.exists(self._get_pushed_consent_file_path()): | 204 if os.path.exists(self._get_pushed_consent_file_path()): |
97 shutil.move(self._get_pushed_consent_file_path(), | 205 shutil.move(self._get_pushed_consent_file_path(), |
98 self._CONSENT_FILE) | 206 self._CONSENT_FILE) |
99 | 207 |
100 | 208 |
101 def _get_crash_dir(self, username): | 209 def _get_crash_dir(self, username): |
210 """Returns full path to the crash directory for a given username | |
211 | |
212 Args: | |
213 username: username to use: | |
214 'chronos': Returns user crash directory. | |
215 'root': Returns system crash directory. | |
216 """ | |
102 if username == 'chronos': | 217 if username == 'chronos': |
103 return self._USER_CRASH_DIR | 218 return self._USER_CRASH_DIR |
104 else: | 219 else: |
105 return self._SYSTEM_CRASH_DIR | 220 return self._SYSTEM_CRASH_DIR |
106 | 221 |
107 | 222 |
108 def _initialize_crash_reporter(self): | 223 def _initialize_crash_reporter(self): |
224 """Start up the crash reporter.""" | |
109 utils.system('%s --init --nounclean_check' % self._CRASH_REPORTER_PATH) | 225 utils.system('%s --init --nounclean_check' % self._CRASH_REPORTER_PATH) |
110 # Completely disable crash_reporter from generating crash dumps | 226 # Completely disable crash_reporter from generating crash dumps |
111 # while any tests are running, otherwise a crashy system can make | 227 # while any tests are running, otherwise a crashy system can make |
112 # these tests flaky. | 228 # these tests flaky. |
113 self.enable_crash_filtering('none') | 229 self.enable_crash_filtering('none') |
114 | 230 |
115 | 231 |
116 def write_crash_dir_entry(self, name, contents): | 232 def write_crash_dir_entry(self, name, contents): |
233 """Writes an empty file to the system crash directory. | |
234 | |
235 This writes a file to _SYSTEM_CRASH_DIR with the given name. This is | |
236 used to insert new crash dump files for testing purposes. | |
237 | |
238 Args: | |
239 name: Name of file to write. | |
240 contents: String to write to the file. | |
241 """ | |
117 entry = os.path.join(self._SYSTEM_CRASH_DIR, name) | 242 entry = os.path.join(self._SYSTEM_CRASH_DIR, name) |
118 if not os.path.exists(self._SYSTEM_CRASH_DIR): | 243 if not os.path.exists(self._SYSTEM_CRASH_DIR): |
119 os.makedirs(self._SYSTEM_CRASH_DIR) | 244 os.makedirs(self._SYSTEM_CRASH_DIR) |
120 utils.open_write_close(entry, contents) | 245 utils.open_write_close(entry, contents) |
121 return entry | 246 return entry |
122 | 247 |
123 | 248 |
124 def write_fake_meta(self, name, exec_name, payload, log=None, | 249 def write_fake_meta(self, name, exec_name, payload, log=None, |
125 complete=True): | 250 complete=True): |
251 """Writes a fake meta entry to the system crash directory. | |
252 | |
253 Args: | |
254 name: Name of file to write. | |
255 exec_name: Value for exec_name item. | |
256 payload: Value for payload item. | |
257 log: Value for log item. | |
258 complete: True to close off the record, otherwise leave it | |
259 incomplete. | |
260 """ | |
126 last_line = '' | 261 last_line = '' |
127 if complete: | 262 if complete: |
128 last_line = 'done=1\n' | 263 last_line = 'done=1\n' |
129 contents = ('exec_name=%s\n' | 264 contents = ('exec_name=%s\n' |
130 'ver=my_ver\n' | 265 'ver=my_ver\n' |
131 'payload=%s\n' | 266 'payload=%s\n' |
132 '%s' % (exec_name, payload, | 267 '%s' % (exec_name, payload, |
133 last_line)) | 268 last_line)) |
134 if log: | 269 if log: |
135 contents = ('log=%s\n' % log) + contents | 270 contents = ('log=%s\n' % log) + contents |
136 return self.write_crash_dir_entry(name, contents) | 271 return self.write_crash_dir_entry(name, contents) |
137 | 272 |
138 | 273 |
139 def _prepare_sender_one_crash(self, | 274 def _prepare_sender_one_crash(self, |
140 send_success, | 275 send_success, |
141 reports_enabled, | 276 reports_enabled, |
142 username, | 277 username, |
143 report): | 278 report): |
279 """Create metadata for a fake crash report. | |
280 | |
281 This enabled mocking of the crash sender, then creates a fake | |
282 crash report for testing purposes. | |
283 | |
284 Args: | |
285 send_success: True to make the crash_sender success, False to make | |
286 it fail. | |
287 reports_enabled: True to enable consent to that reports will be | |
288 sent. | |
289 **username: not used | |
kmixter1
2011/02/25 00:15:15
Feel free to remove this.
| |
290 report: Report to use for crash, if None we create one. | |
291 """ | |
144 self._set_sending_mock(mock_enabled=True, send_success=send_success) | 292 self._set_sending_mock(mock_enabled=True, send_success=send_success) |
145 self._set_consent(reports_enabled) | 293 self._set_consent(reports_enabled) |
146 if report is None: | 294 if report is None: |
147 payload = self.write_crash_dir_entry('fake.dmp', '') | 295 payload = self.write_crash_dir_entry('fake.dmp', '') |
148 report = self.write_fake_meta('fake.meta', 'fake', payload) | 296 report = self.write_fake_meta('fake.meta', 'fake', payload) |
149 return report | 297 return report |
150 | 298 |
151 | 299 |
152 def _parse_sender_output(self, output): | 300 def _parse_sender_output(self, output): |
153 """Parse the log output from the crash_sender script. | 301 """Parse the log output from the crash_sender script. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 # Show the result for debugging but remove 'output' key | 432 # Show the result for debugging but remove 'output' key |
285 # since it's large and earlier in debug output. | 433 # since it's large and earlier in debug output. |
286 debug_result = dict(result) | 434 debug_result = dict(result) |
287 del debug_result['output'] | 435 del debug_result['output'] |
288 logging.debug('Result of send (besides output): %s' % debug_result) | 436 logging.debug('Result of send (besides output): %s' % debug_result) |
289 | 437 |
290 return result | 438 return result |
291 | 439 |
292 | 440 |
293 def _replace_crash_reporter_filter_in(self, new_parameter): | 441 def _replace_crash_reporter_filter_in(self, new_parameter): |
442 """Replaces the --filter_in= parameter of the crash reporter. | |
443 | |
444 The kernel is set up to call the crash reporter with the core dump | |
445 as stdin when a process dies. This function adds a filter to the | |
446 command line used to call the crash reporter. This is used to ignore | |
447 crashes in which we have no interest. | |
448 | |
449 This removes any --filter_in= parameter and optionally replaces it | |
450 with a new one. | |
451 | |
452 Args: | |
453 new_parameter: This is parameter to add to the command line | |
454 instead of the --filter_in=... that was there. | |
455 """ | |
294 core_pattern = utils.read_file(self._CORE_PATTERN)[:-1] | 456 core_pattern = utils.read_file(self._CORE_PATTERN)[:-1] |
295 core_pattern = re.sub('--filter_in=\S*\s*', '', | 457 core_pattern = re.sub('--filter_in=\S*\s*', '', |
296 core_pattern).rstrip() | 458 core_pattern).rstrip() |
297 if new_parameter: | 459 if new_parameter: |
298 core_pattern += ' ' + new_parameter | 460 core_pattern += ' ' + new_parameter |
299 utils.system('echo "%s" > %s' % (core_pattern, self._CORE_PATTERN)) | 461 utils.system('echo "%s" > %s' % (core_pattern, self._CORE_PATTERN)) |
300 | 462 |
301 | 463 |
302 def enable_crash_filtering(self, name): | 464 def enable_crash_filtering(self, name): |
465 """Add a --filter_in argument to the kernel core dump cmdline. | |
466 | |
467 Args: | |
468 name: Filter text to use. This is passed as a --filter_in | |
469 argument to the crash reporter. | |
470 """ | |
303 self._replace_crash_reporter_filter_in('--filter_in=' + name) | 471 self._replace_crash_reporter_filter_in('--filter_in=' + name) |
304 | 472 |
305 | 473 |
306 def disable_crash_filtering(self): | 474 def disable_crash_filtering(self): |
475 """Remove the --filter_in argument from the kernel core dump cmdline. | |
476 | |
477 Next time the crash reporter is invoked (due to a crash) it will not | |
478 receive a --filter_in paramter.""" | |
307 self._replace_crash_reporter_filter_in('') | 479 self._replace_crash_reporter_filter_in('') |
308 | 480 |
309 | 481 |
310 def initialize(self): | 482 def initialize(self): |
483 """Initalize the test.""" | |
311 test.test.initialize(self) | 484 test.test.initialize(self) |
312 self._log_reader = cros_logging.LogReader() | 485 self._log_reader = cros_logging.LogReader() |
313 self._leave_crash_sending = True | 486 self._leave_crash_sending = True |
314 self._automatic_consent_saving = True | 487 self._automatic_consent_saving = True |
315 self.enable_crash_filtering('none') | 488 self.enable_crash_filtering('none') |
316 | 489 |
317 | 490 |
318 def cleanup(self): | 491 def cleanup(self): |
492 """Cleanup after the test. | |
493 | |
494 We reset things back to the way we think they should be. This is | |
495 intended to allow the system to continue normal operation. | |
496 | |
497 - Reset rate limiting. | |
kmixter1
2011/02/25 00:15:15
I'd prefer not to list things at this level since
| |
498 - Clear any spooled crashes. | |
499 - Turn off mocking of crash sending. | |
500 - Maybe pop the consent. | |
501 - disable filtering of crash info. | |
502 | |
503 Some variables change the behavior: | |
504 _automatic_consent_saving: if True, we pop the consent file. | |
505 _leave_crash_sending: True to enable crash sending, False to | |
506 disable it | |
507 """ | |
319 self._reset_rate_limiting() | 508 self._reset_rate_limiting() |
320 self._clear_spooled_crashes() | 509 self._clear_spooled_crashes() |
321 self._set_system_sending(self._leave_crash_sending) | 510 self._set_system_sending(self._leave_crash_sending) |
322 self._set_sending_mock(mock_enabled=False) | 511 self._set_sending_mock(mock_enabled=False) |
323 if self._automatic_consent_saving: | 512 if self._automatic_consent_saving: |
324 self._pop_consent() | 513 self._pop_consent() |
325 self.disable_crash_filtering() | 514 self.disable_crash_filtering() |
326 test.test.cleanup(self) | 515 test.test.cleanup(self) |
327 | 516 |
328 | 517 |
329 def run_crash_tests(self, | 518 def run_crash_tests(self, |
330 test_names, | 519 test_names, |
331 initialize_crash_reporter=False, | 520 initialize_crash_reporter=False, |
332 clear_spool_first=True, | 521 clear_spool_first=True, |
333 must_run_all=True): | 522 must_run_all=True): |
334 """Run crash tests defined in this class. | 523 """Run crash tests defined in this class. |
335 | 524 |
336 Args: | 525 Args: |
337 test_names: array of test names | 526 test_names: Array of test names. |
338 initialize_crash_reporter: should set up crash reporter for every run | 527 initialize_crash_reporter: Should set up crash reporter for every |
339 must_run_all: should make sure every test in this class is mentioned | 528 run. |
340 in test_names | 529 clear_spool_first: Clear all spooled user/system crashes before |
530 starting the test. | |
531 must_run_all: Should make sure every test in this class is | |
532 mentioned in test_names. | |
341 """ | 533 """ |
342 if self._automatic_consent_saving: | 534 if self._automatic_consent_saving: |
343 self._push_consent() | 535 self._push_consent() |
344 | 536 |
345 if must_run_all: | 537 if must_run_all: |
346 # Sanity check test_names is complete | 538 # Sanity check test_names is complete |
347 for attr in dir(self): | 539 for attr in dir(self): |
348 if attr.find('_test_') == 0: | 540 if attr.find('_test_') == 0: |
349 test_name = attr[6:] | 541 test_name = attr[6:] |
350 if not test_name in test_names: | 542 if not test_name in test_names: |
351 raise error.TestError('Test %s is missing' % test_name) | 543 raise error.TestError('Test %s is missing' % test_name) |
352 | 544 |
353 for test_name in test_names: | 545 for test_name in test_names: |
354 logging.info(('=' * 20) + ('Running %s' % test_name) + ('=' * 20)) | 546 logging.info(('=' * 20) + ('Running %s' % test_name) + ('=' * 20)) |
355 if initialize_crash_reporter: | 547 if initialize_crash_reporter: |
356 self._initialize_crash_reporter() | 548 self._initialize_crash_reporter() |
357 # Disable crash_sender from running, kill off any running ones, but | 549 # Disable crash_sender from running, kill off any running ones, but |
358 # set environment so crash_sender may run as a child process. | 550 # set environment so crash_sender may run as a child process. |
359 self._set_system_sending(False) | 551 self._set_system_sending(False) |
360 self._set_child_sending(True) | 552 self._set_child_sending(True) |
361 self._kill_running_sender() | 553 self._kill_running_sender() |
362 self._reset_rate_limiting() | 554 self._reset_rate_limiting() |
363 if clear_spool_first: | 555 if clear_spool_first: |
364 self._clear_spooled_crashes() | 556 self._clear_spooled_crashes() |
557 | |
558 # Call the test function | |
365 getattr(self, '_test_' + test_name)() | 559 getattr(self, '_test_' + test_name)() |
OLD | NEW |