| Index: server/site_tests/platform_KernelErrorPaths/platform_KernelErrorPaths.py
|
| diff --git a/server/site_tests/platform_KernelErrorPaths/platform_KernelErrorPaths.py b/server/site_tests/platform_KernelErrorPaths/platform_KernelErrorPaths.py
|
| index 6ef099fb987317007b97cc7e35c3db046807acc2..423cfaa5dbe6c98a774096de926be5699d54f8ce 100644
|
| --- a/server/site_tests/platform_KernelErrorPaths/platform_KernelErrorPaths.py
|
| +++ b/server/site_tests/platform_KernelErrorPaths/platform_KernelErrorPaths.py
|
| @@ -2,103 +2,80 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -import logging, os, re, shutil
|
| -from autotest_lib.server import test, autotest
|
| +import logging, os
|
| +
|
| from autotest_lib.client.common_lib import error
|
| +from autotest_lib.client.cros.crash_test import CrashTest as CrashTestDefs
|
| +from autotest_lib.server import test
|
|
|
| class platform_KernelErrorPaths(test.test):
|
| version = 1
|
|
|
| - def breakme(self, command):
|
| - logging.info('KernelErrorPaths: causing %s on host %s' %
|
| + def breakme(self, text):
|
| + command = "echo %s > /proc/breakme" % text
|
| + logging.info("KernelErrorPaths: executing '%s' on %s" %
|
| (command, self.client.hostname))
|
| try:
|
| - self.client.run("echo %s > /proc/breakme" % command)
|
| + # Simple sending text into /proc/breakme resets the target
|
| + # immediately, leaving files unsaved to disk and the master ssh
|
| + # connection wedged for a long time. The sequence below borrowed
|
| + # from logging_KernelCrashServer.py makes sure that the test
|
| + # proceeds smoothly.
|
| + self.client.run(
|
| + 'sh -c "sync; sleep 1; %s" >/dev/null 2>&1 &' % command)
|
| except error.AutoservRunError, e:
|
| - # it is expected that this will cause a non-zero exit status
|
| + # It is expected that this will cause a non-zero exit status.
|
| pass
|
|
|
| -
|
| - def test_bug(self):
|
| - """
|
| - Cause the target to log a kernel bug, and then check in the
|
| - messages to make sure it did.
|
| - """
|
| - # Clear the messages so we can compare.
|
| - self.client.run('dmesg -c')
|
| - # Cause the client to report a kernel BUG.
|
| - self.breakme('bug')
|
| - # Now get messages and check to make sure it's in there.
|
| - result = self.client.run('dmesg')
|
| - marker = "Kernel BUG at"
|
| - found = False
|
| - for line in result.stdout.split('\n'):
|
| - if line.find(marker) != -1:
|
| - found = True
|
| - break
|
| - if not found:
|
| - raise error.TestFail("Kernel BUG reporting not working.")
|
| -
|
| -
|
| - def test_deadlock(self):
|
| - # Cause the target to go into a deadlock (have to run it twice).
|
| - self.breakme('deadlock')
|
| - self.breakme('deadlock')
|
| -
|
| -
|
| - def test_soft_lockup(self):
|
| - # Cause the target to go into an infinite loop.
|
| - self.breakme('softlockup')
|
| -
|
| -
|
| - def test_irq_lockup(self):
|
| - # Cause the target to go into a lockup with interrupts enabled.
|
| - self.breakme('irqlockup')
|
| -
|
| -
|
| - def test_no_irq_lockup(self):
|
| - # Cause the target to go into a lockup with interrupts disabled.
|
| - self.breakme('nmiwatchdog')
|
| -
|
| -
|
| - def test_null_dereference(self):
|
| - # Clear the messages so we can compare.
|
| - self.client.run('dmesg -c')
|
| - # Cause the target to dereference a null pointer.
|
| - self.breakme('nullptr')
|
| - # Now get messages and check to make sure it was noticed.
|
| - result = self.client.run('dmesg')
|
| - found = False
|
| - marker = "BUG: unable to handle kernel NULL pointer dereference"
|
| - for line in result.stdout.split('\n'):
|
| - if line.find(marker) != -1:
|
| - found = True
|
| - break
|
| - if not found:
|
| - raise error.TestFail("Kernel NULL pointer dereference detection "
|
| - "not working.")
|
| -
|
| -
|
| - def test_panic(self):
|
| - # Cause the target to panic.
|
| - self.breakme('panic')
|
| - if not self.client.wait_down(timeout=30):
|
| - raise error.TestFail("Kernel panic went unnoticed.")
|
| - if not self.client.wait_up(timeout=40):
|
| - raise error.TestFail("Kernel panic didn't cause successful reboot.")
|
| -
|
| + def configure_crash_reporting(self):
|
| + self._preserved_files = []
|
| + for f in (CrashTestDefs._PAUSE_FILE, CrashTestDefs._CONSENT_FILE):
|
| + result = self.client.run('ls -1 "%s"' % os.path.dirname(f))
|
| + if os.path.basename(f) in result.stdout.splitlines():
|
| + result = self.client.run('cat "%s"' % f)
|
| + self._preserved_files.append((f, result.stdout))
|
| + else:
|
| + self._preserved_files.append((f, None))
|
| +
|
| + self.client.run('touch "%s"' % CrashTestDefs._PAUSE_FILE)
|
| + self.client.run(
|
| + 'echo test-consent > "%s"' % CrashTestDefs._CONSENT_FILE)
|
| +
|
| + def cleanup(self):
|
| + for f, text in self._preserved_files:
|
| + if text is None:
|
| + self.client.run('rm -f "%s"' % f)
|
| + continue
|
| + self.client.run('cat <<EOF >"%s"\n%s\nEOF\n' % (f, text))
|
| + test.test.cleanup(self)
|
|
|
| def run_once(self, host=None):
|
| self.client = host
|
| -
|
| - self.test_bug()
|
| - # TODO: Fill in the tests for these.
|
| - # self.test_deadlock()
|
| - # self.test_soft_lockup()
|
| - # self.test_irq_lockup()
|
| - # self.test_no_irq_lockup()
|
| - self.test_null_dereference()
|
| - # TODO(mbligh): crosbug.com/2269 - panic currently halts the
|
| - # DUT instead of rebooting it. Commenting out until
|
| - # fixed.
|
| - #self.test_panic()
|
| + self.configure_crash_reporting()
|
| +
|
| + crash_log_dir = CrashTestDefs._SYSTEM_CRASH_DIR
|
| +
|
| + # Each tuple consists of two strings: the 'breakme' string to send
|
| + # into /proc/breakme on the target, and the crash report string to
|
| + # look for in the crash dump after target restarts.
|
| + # TODO(vbendeb): add the following breakme strings after fixing kernel
|
| + # bugs:
|
| + # 'deadlock' (has to be sent twice), 'softlockup', 'irqlockup'
|
| + test_tuples = (
|
| + ('bug', 'kernel BUG at'),
|
| + ('nmiwatchdog', 'BUG: NMI Watchdog detected LOCKUP'),
|
| + ('nullptr',
|
| + 'BUG: unable to handle kernel NULL pointer dereference at'),
|
| + ('panic', 'Kernel panic - not syncing:'),
|
| + )
|
| +
|
| + for action, text in test_tuples:
|
| + # Delete crash results, if any
|
| + self.client.run('rm -f %s/*' % crash_log_dir)
|
| + boot_id = self.client.get_boot_id()
|
| + self.breakme(action) # This should cause target reset.
|
| + self.client.wait_for_restart(timeout=25, old_boot_id=boot_id)
|
| + result = self.client.run('cat %s/kernel.*.kcrash' % crash_log_dir)
|
| + if text not in result.stdout:
|
| + raise error.TestFail(
|
| + "No '%s' in the log after sending '%s'" % (text, action))
|
|
|