1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import gzip, logging, os, utils 6 from autotest_lib.client.bin import utils 7 from autotest_lib.client.common_lib import error 8 from autotest_lib.client.cros import crash_test 9 10 11 class logging_UdevCrash(crash_test.CrashTest): 12 """Verify udev triggered crash works as expected.""" 13 version = 1 14 15 16 def CheckAtmelCrashes(self): 17 """Check proper Atmel trackpad crash reports are created.""" 18 if not os.path.exists(self._SYSTEM_CRASH_DIR): 19 return False 20 21 for filename in os.listdir(self._SYSTEM_CRASH_DIR): 22 if not filename.startswith('change__i2c_atmel_mxt_ts'): 23 raise error.TestFail('Crash report %s has wrong name' % 24 filename) 25 if filename.endswith('meta'): 26 continue 27 28 filepath = os.path.join(self._SYSTEM_CRASH_DIR, filename) 29 if filename.endswith('.log.gz'): 30 f = gzip.open(filepath, 'r') 31 elif filename.endswith('.log'): 32 f = open(filepath) 33 else: 34 raise error.TestFail('Crash report %s has wrong extension' % 35 filename) 36 37 data = f.read() 38 # Check that we have seen the end of the file. Otherwise we could 39 # end up racing bwtween writing to the log file and reading/checking 40 # the log file. 41 if 'END-OF-LOG' not in data: 42 continue 43 44 lines = data.splitlines() 45 bad_lines = [x for x in lines if 'atmel_mxt_ts' not in x 46 and 'END-OF-LOG' not in x] 47 if bad_lines: 48 raise error.TestFail('Crash report contains invalid ' 49 'content %s' % bad_lines) 50 return True 51 52 return False 53 54 def _test_udev_report_atmel(self): 55 """Test that atmel trackpad failure can trigger udev crash report.""" 56 DRIVER_DIR = '/sys/bus/i2c/drivers/atmel_mxt_ts' 57 has_atmel_device = False 58 if os.path.exists(DRIVER_DIR): 59 for filename in os.listdir(DRIVER_DIR): 60 if os.path.isdir(os.path.join(DRIVER_DIR, filename)): 61 has_atmel_device = True 62 63 if not has_atmel_device: 64 logging.info('No atmel device, skip the test') 65 return None 66 67 self._set_consent(True) 68 69 # Use udevadm to trigger a fake udev event representing atmel driver 70 # failure. The uevent match rule in 99-crash-reporter.rules is 71 # ACTION=="change", SUBSYSTEM=="i2c", DRIVER=="atmel_mxt_ts", 72 # ENV{ERROR}=="1" RUN+="/sbin/crash_reporter 73 # --udev=SUBSYSTEM=i2c-atmel_mxt_ts:ACTION=change" 74 utils.system('udevadm control --property=ERROR=1', 75 ignore_status=True) 76 utils.system('udevadm trigger ' 77 '--action=change ' 78 '--subsystem-match=i2c ' 79 '--attr-match=driver=atmel_mxt_ts', 80 ignore_status=True) 81 utils.system('udevadm control --property=ERROR=0', 82 ignore_status=True) 83 84 utils.poll_for_condition( 85 self.CheckAtmelCrashes, 86 timeout=60, 87 exception=error.TestFail('No valid Atmel crash reports')) 88 89 def run_once(self): 90 self._automatic_consent_saving = True 91 self.run_crash_tests(['udev_report_atmel'], True) 92