blob: 232a16ba1bcbcb530c79556ac74eeb6f8cad109a [file] [log] [blame]
# Copyright 2013 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.
"""Uses ectool to control the onboard LED light, and lets either operator
or SMT fixture confirm LED functionality."""
import logging
import random
import factory_common # pylint: disable=unused-import
from cros.factory.device import device_utils
from cros.factory.device import led as led_module
# The right BFTFixture module is dynamically imported based on args.bft_fixture.
# See setUp() for more detail.
from cros.factory.test.fixture import bft_fixture
from cros.factory.test.i18n import _
from cros.factory.test import test_case
from cros.factory.utils.arg_utils import Arg
LEDColor = led_module.LED.Color
LEDIndex = led_module.LED.CrOSIndexes
_COLOR_LABEL = {
LEDColor.YELLOW: _('yellow'),
LEDColor.GREEN: _('green'),
LEDColor.RED: _('red'),
LEDColor.WHITE: _('white'),
LEDColor.BLUE: _('blue'),
LEDColor.AMBER: _('amber'),
LEDColor.OFF: _('off')}
_INDEX_LABEL = {
None: _('LED'),
LEDIndex.POWER: _('power LED'),
LEDIndex.BATTERY: _('battery LED'),
LEDIndex.ADAPTER: _('adapter LED'),
LEDIndex.LEFT: _('left LED'),
LEDIndex.RIGHT: _('right LED'),
LEDIndex.RECOVERY_HWREINIT: _('recovery hwreinit LED'),
getattr(LEDIndex, 'SYSRQ DEBUG'): _('sysrq debug LED')}
class LEDTest(test_case.TestCase):
"""Tests if the onboard LED can light up with specified colors."""
ARGS = [
Arg('bft_fixture', dict, bft_fixture.TEST_ARG_HELP, default=None),
Arg('challenge', bool, 'Show random LED sequence and let the operator '
'select LED number instead of pre-defined sequence.', default=False),
Arg('colors', list,
'List of colors or [index, color] to test. color must be in '
'LEDColor or OFF, and index, if specified, must be in LEDIndex.',
default=[LEDColor.YELLOW, LEDColor.GREEN, LEDColor.RED,
LEDColor.OFF]),
Arg('target_leds', list,
'List of LEDs to test. If specified, it turns off all LEDs first, '
'and sets them to auto after test.', default=None)]
def setUp(self):
self._led = device_utils.CreateDUTInterface().led
self._fixture = None
if self.args.bft_fixture:
self._fixture = bft_fixture.CreateBFTFixture(**self.args.bft_fixture)
self._SetAllLED(LEDColor.OFF)
# Transform the colors to a list of [led_name, color].
self.colors = [[None, item] if isinstance(item, basestring) else item
for item in self.args.colors]
# Shuffle the colors for interactive challenge, so operators can't guess
# the sequence.
if self.args.challenge:
random.shuffle(self.colors)
for test_id, [led_name, color] in enumerate(self.colors, 1):
if self._fixture:
self.AddTask(self.RunFixtureTask, led_name, color)
elif self.args.challenge:
self.AddTask(self.RunChallengeTask, test_id, led_name, color)
else:
self.AddTask(self.RunNormalTask, led_name, color)
def tearDown(self):
self._SetAllLED(LEDColor.AUTO)
if self._fixture:
self._fixture.Disconnect()
def RunNormalTask(self, led_name, color):
"""Checks for LED colors by asking operator to push ENTER."""
try:
self._SetLEDColor(led_name, color)
led_name_label = self._GetNameI18nLabel(led_name)
color_label = _COLOR_LABEL[color]
if color == LEDColor.OFF:
instruction = _(
'If the <strong>{name}</strong> is <strong>off</strong>, '
'press ENTER.',
name=led_name_label)
else:
instruction = _(
'If the <strong>{name}</strong> lights up in '
'<strong>{color}</strong>, press ENTER.',
name=led_name_label,
color=color_label)
self.ui.SetState(instruction)
self.ui.BindStandardKeys()
self.WaitTaskEnd()
finally:
self._TurnOffLED(led_name)
def _CreateChallengeTaskUI(self, test_id, led_name, color_options):
"""Create the UI of challenge task."""
def _MakeButton(idx, color):
return '<span class="led-btn color-{color}">{idx}</span>'.format(
color=color.lower(), idx=idx)
led_name_label = self._GetNameI18nLabel(led_name)
description = [
'<span class="sub-title">',
_('Test {test_id}', test_id=test_id), '</span>',
_('Please press number key according to the <strong>{name}</strong> '
'color',
name=led_name_label)
]
buttons_ui = [
'<div>',
[_MakeButton(idx, color)
for idx, color in enumerate(color_options, 1)], '</div>'
]
result_line = [
'<div class="result-line">',
_('Result: '), '<span id="result"></span></div>'
]
return [description, '<br>', buttons_ui, result_line]
def RunChallengeTask(self, test_id, led_name, color):
"""Checks for LED colors interactively."""
try:
self._SetLEDColor(led_name, color)
color_options = sorted(set(color for unused_index, color in self.colors))
answer = color_options.index(color)
self.ui.SetState(
self._CreateChallengeTaskUI(test_id, led_name, color_options))
keys = [str(i) for i in range(1, len(color_options) + 1)]
pressed_key = int(self.ui.WaitKeysOnce(keys)) - 1
if pressed_key == answer:
self.ui.SetHTML('<span class="result-pass">PASS</span>', id='result')
self.Sleep(0.5)
self.PassTask()
else:
self.ui.SetHTML('<span class="result-fail">FAIL</span>', id='result')
self.Sleep(0.5)
self.FailTask('correct color for %s is %s but got %s.' %
(led_name, color, color_options[pressed_key]))
finally:
self._TurnOffLED(led_name)
def RunFixtureTask(self, led_name, color):
"""Lights LED in color and asks fixture to verify it."""
try:
self._SetLEDColor(led_name, color)
try:
if self._fixture.IsLEDColor(color):
self.PassTask()
else:
# Fail later to detect all colors.
self.FailTask('Unable to detect %s LED.' % color)
except bft_fixture.BFTFixtureException:
logging.exception('Failed to send command to BFT fixture')
self.FailTask('Failed to send command to BFT fixture.')
finally:
self._TurnOffLED(led_name)
def _SetLEDColor(self, led_name, color):
"""Set LED color for a led."""
if led_name is None:
self._led.SetColor(color)
else:
self._led.SetColor(color, led_name=led_name)
def _TurnOffLED(self, led_name):
"""Turn off the target LED."""
self._SetLEDColor(led_name, LEDColor.OFF)
def _GetNameI18nLabel(self, led_name):
return _INDEX_LABEL.get(led_name, _(led_name))
def _SetAllLED(self, color):
"""Sets all LEDs in target_leds to a given color.
Args:
color: One of LEDColor.
"""
if self.args.target_leds:
for led in self.args.target_leds:
self._led.SetColor(color, led_name=led)
else:
self._led.SetColor(color)