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 |
6 from autotest_lib.server import test, autotest | 6 |
7 from autotest_lib.client.common_lib import error | 7 from autotest_lib.client.common_lib import error |
8 from autotest_lib.client.cros.crash_test import CrashTest as CrashTestDefs | |
9 from autotest_lib.server import test | |
8 | 10 |
9 class platform_KernelErrorPaths(test.test): | 11 class platform_KernelErrorPaths(test.test): |
10 version = 1 | 12 version = 1 |
11 | 13 |
12 def breakme(self, command): | 14 def breakme(self, text): |
13 logging.info('KernelErrorPaths: causing %s on host %s' % | 15 command = "echo %s > /proc/breakme" % text |
16 logging.info("KernelErrorPaths: executing '%s' on %s" % | |
14 (command, self.client.hostname)) | 17 (command, self.client.hostname)) |
15 try: | 18 try: |
16 self.client.run("echo %s > /proc/breakme" % command) | 19 self.client.run(command) |
17 except error.AutoservRunError, e: | 20 except error.AutoservRunError, e: |
18 # it is expected that this will cause a non-zero exit status | 21 # it is expected that this will cause a non-zero exit status |
19 pass | 22 pass |
20 | 23 |
24 def pause_crash_sending(self): | |
25 result = self.client.run( | |
26 'ls %s' % os.path.dirname(CrashTestDefs._PAUSE_FILE)) | |
27 self.client.run('touch %s' % CrashTestDefs._PAUSE_FILE) | |
28 return not os.path.basename( | |
29 CrashTestDefs._PAUSE_FILE) in result.stdout.splitlines() | |
21 | 30 |
22 def test_bug(self): | 31 def resume_crash_sending(self): |
petkov
2011/02/25 19:54:35
who calls this method? it seems it needs to be cal
vb
2011/02/25 23:27:37
right, this got lost when I cleaned up the code be
| |
23 """ | 32 self.client.run('rm -f %s' % CrashTestDefs._PAUSE_FILE) |
24 Cause the target to log a kernel bug, and then check in the | |
25 messages to make sure it did. | |
26 """ | |
27 # Clear the messages so we can compare. | |
28 self.client.run('dmesg -c') | |
29 # Cause the client to report a kernel BUG. | |
30 self.breakme('bug') | |
31 # Now get messages and check to make sure it's in there. | |
32 result = self.client.run('dmesg') | |
33 marker = "Kernel BUG at" | |
34 found = False | |
35 for line in result.stdout.split('\n'): | |
36 if line.find(marker) != -1: | |
37 found = True | |
38 break | |
39 if not found: | |
40 raise error.TestFail("Kernel BUG reporting not working.") | |
41 | |
42 | |
43 def test_deadlock(self): | |
44 # Cause the target to go into a deadlock (have to run it twice). | |
45 self.breakme('deadlock') | |
46 self.breakme('deadlock') | |
47 | |
48 | |
49 def test_soft_lockup(self): | |
50 # Cause the target to go into an infinite loop. | |
51 self.breakme('softlockup') | |
52 | |
53 | |
54 def test_irq_lockup(self): | |
55 # Cause the target to go into a lockup with interrupts enabled. | |
56 self.breakme('irqlockup') | |
57 | |
58 | |
59 def test_no_irq_lockup(self): | |
60 # Cause the target to go into a lockup with interrupts disabled. | |
61 self.breakme('nmiwatchdog') | |
62 | |
63 | |
64 def test_null_dereference(self): | |
65 # Clear the messages so we can compare. | |
66 self.client.run('dmesg -c') | |
67 # Cause the target to dereference a null pointer. | |
68 self.breakme('nullptr') | |
69 # Now get messages and check to make sure it was noticed. | |
70 result = self.client.run('dmesg') | |
71 found = False | |
72 marker = "BUG: unable to handle kernel NULL pointer dereference" | |
73 for line in result.stdout.split('\n'): | |
74 if line.find(marker) != -1: | |
75 found = True | |
76 break | |
77 if not found: | |
78 raise error.TestFail("Kernel NULL pointer dereference detection " | |
79 "not working.") | |
80 | |
81 | |
82 def test_panic(self): | |
83 # Cause the target to panic. | |
84 self.breakme('panic') | |
85 if not self.client.wait_down(timeout=30): | |
86 raise error.TestFail("Kernel panic went unnoticed.") | |
87 if not self.client.wait_up(timeout=40): | |
88 raise error.TestFail("Kernel panic didn't cause successful reboot.") | |
89 | |
90 | 33 |
91 def run_once(self, host=None): | 34 def run_once(self, host=None): |
92 self.client = host | 35 self.client = host |
93 | 36 |
94 self.test_bug() | 37 crash_sending_needs_resuming = self.pause_crash_sending() |
petkov
2011/02/25 19:54:35
unused?
| |
95 # TODO: Fill in the tests for these. | 38 |
96 # self.test_deadlock() | 39 crash_log_dir = CrashTestDefs._SYSTEM_CRASH_DIR |
97 # self.test_soft_lockup() | 40 |
98 # self.test_irq_lockup() | 41 # Each tuple consists of two strings: the 'breakme' string to send |
99 # self.test_no_irq_lockup() | 42 # into /proc/breakme on the target, and the crash report string to |
100 self.test_null_dereference() | 43 # look for in the crash dump after target restarts. |
101 # TODO(mbligh): crosbug.com/2269 - panic currently halts the | 44 # TODO(vbendeb): add the following breakme strings after fixing kernel |
102 # DUT instead of rebooting it. Commenting out until | 45 # bugs: |
103 # fixed. | 46 # 'deadlock' (has to be sent twice), 'softlockup', 'irqlockup' |
104 #self.test_panic() | 47 test_tuples = ( |
48 ('bug', 'kernel BUG at'), | |
49 ('nmiwatchdog', 'BUG: NMI Watchdog detected LOCKUP'), | |
50 ('nullptr', | |
51 'BUG: unable to handle kernel NULL pointer dereference at'), | |
52 ('panic', 'Kernel panic - not syncing:'), | |
53 ) | |
54 | |
55 for action, text in test_tuples: | |
56 # Delete crash results, if any | |
57 self.client.run('rm -f %s/*' % crash_log_dir) | |
58 boot_id = self.client.get_boot_id() | |
59 self.breakme(action) # This should cause target reset. | |
60 self.client.wait_for_restart(timeout=25, old_boot_id=boot_id) | |
61 result = self.client.run('cat %s/kernel.*.kcrash' % crash_log_dir) | |
62 if text not in result.stdout: | |
63 raise error.TestFail( | |
64 "No '%s' in the log after sending '%s'" % (text, cmd)) | |
OLD | NEW |