Home | History | Annotate | Download | only in detachablebase_TriggerHammerd
      1 # Copyright 2017 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 logging
      6 
      7 from autotest_lib.client.bin import test
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.common_lib import utils
     10 
     11 
     12 class detachablebase_TriggerHammerd(test.test):
     13     """Hammerd smoke test.
     14 
     15     Hammerd upstart job should be invoked on boot. The job should exit normally.
     16 
     17     Also, checks that hammerd enables USB autosuspend on the hammer device.
     18     """
     19     version = 1
     20 
     21     # The upstart job's name.
     22     PROCESS_NAME = 'hammerd'
     23 
     24     # Path of the system log.
     25     MESSAGE_PATH = '/var/log/messages'
     26 
     27     # Message to find the start line of each boot. The boot timing is usually
     28     # [    0.000000], but in case the boot process has delay, we accept any
     29     # timing within 1 second.
     30     BOOT_START_LINE_MSG = 'kernel: \[    0\.[0-9]\{6\}\] Linux version'
     31 
     32     # Message that is printed when hammerd is triggered on boot.
     33     # It is defined at `src/platform2/hammerd/init/hammerd-at-boot.sh`.
     34     TRIGGER_ON_BOOT_MSG = 'Force trigger hammerd at boot.'
     35 
     36     # Message that is printed when the hammerd job failed to terminated
     37     # normally.
     38     PROCESS_FAILED_MSG = '%s main process ([0-9]\+) terminated' % PROCESS_NAME
     39 
     40     # Hammerd writes path to USB device in that file.
     41     WRITE_SYSFS_PATH = '/run/hammer_sysfs_path'
     42 
     43     # Autosuspend control sysfs PATH (rooted at USB device sysfs path)
     44     SYSFS_POWER_CONTROL_PATH = 'power/control'
     45 
     46     def run_once(self):
     47         # Get the start line of message belonging to this current boot.
     48         start_line = utils.run(
     49                 'grep -ni "%s" "%s" | tail -n 1 | cut -d ":" -f 1' %
     50                 (self.BOOT_START_LINE_MSG, self.MESSAGE_PATH),
     51                 ignore_status=True).stdout.strip()
     52         logging.info('Start line: %s', start_line)
     53         if not start_line:
     54             raise error.TestFail('Start line of boot is not found.')
     55 
     56         def _grep_messages(pattern):
     57             return utils.run('tail -n +%s %s | grep "%s"' %
     58                              (start_line, self.MESSAGE_PATH, pattern),
     59                              ignore_status=True).stdout
     60 
     61         # Check hammerd is triggered on boot.
     62         if not _grep_messages(self.TRIGGER_ON_BOOT_MSG):
     63             raise error.TestFail('hammerd is not triggered on boot.')
     64         # Check hammerd is terminated normally.
     65         if _grep_messages(self.PROCESS_FAILED_MSG):
     66             hammerd_log = _grep_messages(self.PROCESS_NAME)
     67             logging.error('Hammerd log: %s', hammerd_log)
     68             raise error.TestFail('hammerd terminated with non-zero value')
     69 
     70         # Check that hammerd wrote to WRITE_SYSFS_PATH
     71         sysfspath = utils.read_one_line(self.WRITE_SYSFS_PATH)
     72 
     73         if not sysfspath:
     74             raise error.TestFail('%s is empty' % (self.WRITE_SYSFS_PATH))
     75 
     76         # Check that autosuspend is enabled
     77         power = utils.read_one_line(sysfspath + '/' +
     78                                     self.SYSFS_POWER_CONTROL_PATH)
     79         if power != 'auto':
     80             raise error.TestFail('Autosuspend not enabled on hammer port')
     81