# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import gzip, logging, os, utils
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import crash_test
class logging_UdevCrash(crash_test.CrashTest):
"""Verify udev triggered crash works as expected."""
version = 1
def CheckAtmelCrashes(self):
"""Check proper Atmel trackpad crash reports are created."""
if not os.path.exists(self._SYSTEM_CRASH_DIR):
return False
for filename in os.listdir(self._SYSTEM_CRASH_DIR):
if not filename.startswith('change__i2c_atmel_mxt_ts'):
raise error.TestFail('Crash report %s has wrong name' %
filename)
if filename.endswith('meta'):
continue
filepath = os.path.join(self._SYSTEM_CRASH_DIR, filename)
if filename.endswith('.log.gz'):
f = gzip.open(filepath, 'r')
elif filename.endswith('.log'):
f = open(filepath)
else:
raise error.TestFail('Crash report %s has wrong extension' %
filename)
data = f.read()
# Check that we have seen the end of the file. Otherwise we could
# end up racing bwtween writing to the log file and reading/checking
# the log file.
if 'END-OF-LOG' not in data:
continue
lines = data.splitlines()
bad_lines = [x for x in lines if 'atmel_mxt_ts' not in x
and 'END-OF-LOG' not in x]
if bad_lines:
raise error.TestFail('Crash report contains invalid '
'content %s' % bad_lines)
return True
return False
def _test_udev_report_atmel(self):
"""Test that atmel trackpad failure can trigger udev crash report."""
DRIVER_DIR = '/sys/bus/i2c/drivers/atmel_mxt_ts'
has_atmel_device = False
if os.path.exists(DRIVER_DIR):
for filename in os.listdir(DRIVER_DIR):
if os.path.isdir(os.path.join(DRIVER_DIR, filename)):
has_atmel_device = True
if not has_atmel_device:
logging.info('No atmel device, skip the test')
return None
self._set_consent(True)
# Use udevadm to trigger a fake udev event representing atmel driver
# failure. The uevent match rule in 99-crash-reporter.rules is
# ACTION=="change", SUBSYSTEM=="i2c", DRIVER=="atmel_mxt_ts",
# ENV{ERROR}=="1" RUN+="/sbin/crash_reporter
# --udev=SUBSYSTEM=i2c-atmel_mxt_ts:ACTION=change"
utils.system('udevadm control --property=ERROR=1',
ignore_status=True)
utils.system('udevadm trigger '
'--action=change '
'--subsystem-match=i2c '
'--attr-match=driver=atmel_mxt_ts',
ignore_status=True)
utils.system('udevadm control --property=ERROR=0',
ignore_status=True)
utils.poll_for_condition(
self.CheckAtmelCrashes,
timeout=60,
exception=error.TestFail('No valid Atmel crash reports'))
def run_once(self):
self._automatic_consent_saving = True
self.run_crash_tests(['udev_report_atmel'], True)