124 lines
3.9 KiB
Python
124 lines
3.9 KiB
Python
# Copyright 2017 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 logging
|
|
import time
|
|
from threading import Timer
|
|
|
|
from autotest_lib.client.bin.input import linux_input
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
|
|
|
|
|
|
class firmware_BaseECKeyboard(FirmwareTest):
|
|
"""Servo-based BaseEC keyboard test.
|
|
|
|
The base should be connected to the servo v4 board through an extra
|
|
micro-servo. It talks to the base EC to emulate key-press.
|
|
"""
|
|
version = 1
|
|
|
|
# Delay to ensure client is ready to read the key press.
|
|
KEY_PRESS_DELAY = 2
|
|
|
|
# Delay to wait until the UI starts.
|
|
START_UI_DELAY = 1
|
|
|
|
# Delay to wait until developer console is open.
|
|
DEV_CONSOLE_DELAY = 2
|
|
|
|
|
|
def initialize(self, host, cmdline_args):
|
|
super(firmware_BaseECKeyboard, self).initialize(host, cmdline_args)
|
|
# Don't require USB disk
|
|
self.setup_usbkey(usbkey=False)
|
|
# Only run in normal mode
|
|
self.switcher.setup_mode('normal')
|
|
|
|
|
|
def cleanup(self):
|
|
# Restart UI anyway, in case the test failed in the middle
|
|
try:
|
|
self.faft_client.system.run_shell_command('start ui | true')
|
|
except Exception as e:
|
|
logging.error("Caught exception: %s", str(e))
|
|
super(firmware_BaseECKeyboard, self).cleanup()
|
|
|
|
|
|
def _base_keyboard_checker(self, press_action):
|
|
"""Press key and check from DUT.
|
|
|
|
Args:
|
|
press_action: A callable that would press the keys when called.
|
|
|
|
Returns:
|
|
True if passed; or False if failed.
|
|
"""
|
|
# Stop UI so that key presses don't go to Chrome.
|
|
self.faft_client.system.run_shell_command('stop ui')
|
|
|
|
# Start a thread to perform the key-press action
|
|
Timer(self.KEY_PRESS_DELAY, press_action).start()
|
|
|
|
# Invoke client side script to monitor keystrokes.
|
|
# The codes are linux input event codes.
|
|
# The order doesn't matter.
|
|
result = self.faft_client.system.check_keys([
|
|
linux_input.KEY_ENTER,
|
|
linux_input.KEY_LEFTCTRL,
|
|
linux_input.KEY_D])
|
|
|
|
# Turn UI back on
|
|
self.faft_client.system.run_shell_command('start ui')
|
|
time.sleep(self.START_UI_DELAY)
|
|
|
|
return result
|
|
|
|
|
|
def keyboard_checker(self):
|
|
"""Press 'd', Ctrl, ENTER by servo and check from DUT."""
|
|
|
|
def keypress(): # pylint:disable=missing-docstring
|
|
self.servo.enter_key()
|
|
self.servo.ctrl_d()
|
|
|
|
return self._base_keyboard_checker(keypress)
|
|
|
|
|
|
def switch_tty2(self):
|
|
"""Switch to tty2 console."""
|
|
self.base_ec.key_down('<ctrl_l>')
|
|
self.base_ec.key_down('<alt_l>')
|
|
self.base_ec.key_down('<f2>')
|
|
self.base_ec.key_up('<f2>')
|
|
self.base_ec.key_up('<alt_l>')
|
|
self.base_ec.key_up('<ctrl_l>')
|
|
time.sleep(self.DEV_CONSOLE_DELAY)
|
|
|
|
|
|
def reboot_by_keyboard(self):
|
|
"""Reboot DUT by keyboard.
|
|
|
|
Simulate key press sequence to log into console and then issue reboot
|
|
command.
|
|
"""
|
|
# Assume that DUT runs a test image, which has tty2 console and root
|
|
# access.
|
|
self.switch_tty2()
|
|
self.base_ec.send_key_string('root<enter>')
|
|
self.base_ec.send_key_string('test0000<enter>')
|
|
self.base_ec.send_key_string('reboot<enter>')
|
|
|
|
|
|
def run_once(self):
|
|
"""Runs a single iteration of the test."""
|
|
if not self.base_ec:
|
|
raise error.TestError('The base not found on servo. Wrong setup?')
|
|
|
|
logging.info('Testing keypress by servo...')
|
|
self.check_state(self.keyboard_checker)
|
|
|
|
logging.info('Use key press simulation to issue reboot command...')
|
|
self.switcher.mode_aware_reboot('custom', self.reboot_by_keyboard)
|