blob: 4ef12465652349aa3d14dbab7a4b32270b0874e2 [file] [log] [blame] [edit]
# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A test to make sure everything is set for the following test in test list.
Description
-----------
This test checks everything is set for the following tests in the test list,
including make sure an external power supplier is presence, checking factory
software is installed, etc.
Normally, this test should be placed as the first one in a test list, to make
sure everything is set before performing any other tests.
Test Procedure
--------------
It checks several conditions as specified by the options, and ask the operator
to press a key to pass.
Dependency
----------
If argument ``require_external_power`` is set, it reads
``/sys/class/power_supply/`` to determine if an external power supply is
connected.
Examples
--------
To initialize shared data, then ask the operator to press a key to continue,
add this in test list::
{
"pytest_name": "start"
}
Ask the operator to press power button to continue, add this in test list::
{
"pytest_name": "start",
"args": {
"key_to_continue": "HW_BUTTON",
"button_key_name": "KEY_POWER",
"button_name": "i18n! Power Button"
}
}
Show custom message::
{
"pytest_name": "start",
"args": {
"prompt": "i18n! Some message..."
}
}
To also ensure if an external power supply is connected, and check factory
toolkit is properly installed::
{
"pytest_name": "start",
"args": {
"check_factory_install_complete": true,
"require_external_power": true
}
}
"""
import enum
import logging
import os
from cros.factory.device import device_utils
from cros.factory.test.event_log import Log
from cros.factory.test.i18n import _
from cros.factory.test.i18n import arg_utils as i18n_arg_utils
from cros.factory.test import session
from cros.factory.test import state
from cros.factory.test import test_case
from cros.factory.test import test_ui
from cros.factory.test.utils import button_utils
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import log_utils
from cros.factory.utils import sync_utils
_LSB_FACTORY_PATH = '/usr/local/etc/lsb-factory'
_AC_CHECK_PERIOD = 0.5
class _KeyType(str, enum.Enum):
NONE = 'NONE'
SPACE = 'SPACE'
HW_BUTTON = 'HW_BUTTON'
def __str__(self):
return self.name
class StartTest(test_case.TestCase):
"""The factory test to start the whole factory test process."""
related_components = tuple()
ARGS = [
Arg(
'key_to_continue', _KeyType,
'The key which need to be pressed to continue. "NONE" means don\'t '
'need to press key to continue.', default=_KeyType.SPACE),
Arg('button_key_name', str, 'The key name to identify the button.',
default=None),
i18n_arg_utils.I18nArg(
'button_name', 'The name of the button to be shown.', default=None),
Arg('require_external_power', bool,
'Prompts and waits for external power to be applied.', default=False),
Arg('check_factory_install_complete', bool,
'Check factory install process was complete.', default=None),
i18n_arg_utils.I18nArg(
'prompt',
'Message to be shown to the operator when prompting for input.',
default=None),
Arg('init_shared_data', dict, 'The shared data to be initialized.',
default={})
]
def setUp(self):
self.dut = device_utils.CreateDUTInterface()
# yapf: disable
self.ui.ToggleTemplateClass('font-large', True) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def WaitHWButton(self):
# yapf: disable
button = button_utils.Button(self.dut, self.args.button_key_name, None) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
sync_utils.WaitFor(button.IsPressed, timeout_secs=None) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def SetStateWithPrompt(self, message):
html = []
# yapf: disable
if self.args.prompt: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
html += [self.args.prompt, '<br><br>'] # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
html += [message]
# yapf: disable
self.ui.SetState(html) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def runTest(self):
# yapf: disable
if self.args.init_shared_data: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.InitializeSharedData()
# yapf: disable
if self.args.check_factory_install_complete: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.CheckFactoryInstallComplete()
# yapf: disable
if self.args.require_external_power: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.CheckExternalPower()
# yapf: disable
if self.args.key_to_continue == _KeyType.SPACE: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.SetStateWithPrompt(_('Hit SPACE to start testing...'))
# yapf: disable
self.ui.WaitKeysOnce(test_ui.SPACE_KEY) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
elif self.args.key_to_continue == _KeyType.HW_BUTTON: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.SetStateWithPrompt(
# yapf: disable
_('Hit {name} to start testing...', name=self.args.button_name)) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.WaitHWButton()
def CheckExternalPower(self):
logger = log_utils.NoisyLogger(logging.info)
# yapf: disable
self.ui.SetState(_('Plug in external power to continue.')) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
while True:
ac_present = self.dut.power.CheckACPresent()
logger.Log('power state: %s', ac_present)
Log('ac_present', state=ac_present)
if ac_present:
break
self.Sleep(_AC_CHECK_PERIOD)
def CheckFactoryInstallComplete(self):
if not os.path.exists(_LSB_FACTORY_PATH):
session.console.error('%s is missing', _LSB_FACTORY_PATH)
# yapf: disable
self.ui.SetState([ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'<span class="test-error">',
_('Factory install process did not complete. '
'Auto-testing stopped.<br><br>'
'Please install the factory test image using factory server<br>'
'rather than booting from a USB drive.<br>'), '</span>'
])
# hangs forever.
self.WaitTaskEnd()
Log('factory_installed')
def InitializeSharedData(self):
# yapf: disable
self.ui.SetState(_('Initialize some shared data...')) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
for key, value in self.args.init_shared_data.items(): # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
session.console.debug('DataShelfSetValue[%s] = "%s"', key, value)
state.DataShelfSetValue(key, value)