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 5import logging 6 7from autotest_lib.client.bin import test 8from autotest_lib.client.common_lib import error 9from autotest_lib.client.common_lib import utils 10 11 12class 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