Home | History | Annotate | Download | only in logging_UdevCrash
      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
      6 from autotest_lib.client.bin import utils
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.client.cros.crash 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