# 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 from autotest_lib.client.bin import utils from autotest_lib.client.common_lib import error from autotest_lib.client.cros.crash 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)