blob: 9c6ac098bb560903a19c5d1291005f5bbeb7bdd7 [file] [log] [blame]
# Copyright 2016 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.
"""A factory test for gyroscopes.
Usage examples::
OperatorTest(
id='Gyroscope',
pytest_name='gyroscope',
dargs={
'rotation_threshold': 1.0,
'stop_threshold': 0.1
})
"""
import collections
import time
import unittest
import factory_common # pylint: disable=unused-import
from cros.factory.device import device_utils
from cros.factory.test import factory_task
from cros.factory.test.i18n import test_ui as i18n_test_ui
from cros.factory.test import test_ui
from cros.factory.test import ui_templates
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import sync_utils
from cros.factory.utils import type_utils
_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
'Please put device on a horizontal plane then press space to '
'start calibration.', 'test-info')
_MSG_IN_PROGRESS = i18n_test_ui.MakeI18nLabelWithClass(
'Please do not move the device.', 'test-info')
_MSG_START_MOVING = i18n_test_ui.MakeI18nLabelWithClass(
'Please rotate the device.', 'test-info')
def GetPreparingMessage(secs):
return i18n_test_ui.MakeI18nLabelWithClass(
'Calibration will be started within {secs} seconds.'
'Please do not move device.',
'test-info',
secs=secs)
_MSG_PASS = i18n_test_ui.MakeI18nLabelWithClass('PASS', 'test-pass')
_MSG_FAIL = i18n_test_ui.MakeI18nLabelWithClass('FAIL', 'test-fail')
_BR = '<br>'
_CSS = """
.test-info {font-size: 2em;}
.test-pass {font-size: 2em; color:green;}
.test-fail {font-size: 2em; color:red;}
"""
class ReadGyroscopeTask(factory_task.FactoryTask):
"""Horizontal calibration for accelerometers.
Attributes:
test: The main Gyroscope TestCase object.
gyroscope: The gyroscope object.
rotation_threshold: The expected value to read when dut start rotating.
stop_threshold: The expected value to read when dut stop moving.
timeout_secs: Maximum retry time for gyro to return expected value.
setup_time_secs: How many seconds to wait after pressing space to
start calibration.
"""
def __init__(self, test, gyroscope, rotation_threshold, stop_threshold,
timeout_secs, setup_time_secs):
super(ReadGyroscopeTask, self).__init__()
self.test = test
self.gyroscope = gyroscope
self.rotation_threshold = rotation_threshold
self.stop_threshold = stop_threshold
self.timeout_secs = timeout_secs
self.setup_time_secs = setup_time_secs
self.template = test.template
def _WaitForDeviceStop(self):
"""Wait until absolute value of all sensors less than stop_threshold."""
def CheckSensorState():
data = self.gyroscope.GetData()
return all(abs(v) < self.stop_threshold for v in data.values())
sync_utils.WaitFor(CheckSensorState, self.timeout_secs)
def _WaitForDeviceRotate(self):
"""Wait until all sensors has absolute value > rotation_threshold."""
max_values = collections.defaultdict(float)
def CheckSensorMaxValues():
data = self.gyroscope.GetData()
for sensor_name in data:
max_values[sensor_name] = max(max_values[sensor_name],
abs(data[sensor_name]))
return all(abs(v) > self.rotation_threshold for v in max_values.values())
sync_utils.WaitFor(CheckSensorMaxValues, self.timeout_secs)
def StartTask(self):
"""Waits a period of time and then starts testing."""
for i in xrange(self.setup_time_secs):
self.template.SetState(GetPreparingMessage(self.setup_time_secs - i))
time.sleep(1)
try:
self.template.SetState(_MSG_IN_PROGRESS)
self._WaitForDeviceStop()
self.template.SetState(_MSG_START_MOVING)
self._WaitForDeviceRotate()
except type_utils.TimeoutError as e:
self.Fail(e.message)
return
self.template.SetState(' ' + _MSG_PASS + _BR, append=True)
self.Pass()
def Run(self):
"""Prompts a message to ask operator to press space."""
self.template.SetState(_MSG_SPACE)
self.test.ui.BindKey(test_ui.SPACE_KEY, lambda _: self.StartTask())
class Gyroscope(unittest.TestCase):
ARGS = [
Arg('rotation_threshold', float,
'The expected value (rad/s) to read when dut start rotating.',
optional=False),
Arg('stop_threshold', float,
'The expected value to read when dut stop moving.',
optional=False),
Arg('timeout_secs', int,
'Timeout in seconds for gyro to return expected value.',
default=30, optional=True),
Arg('setup_time_secs', int,
'Seconds to wait before starting the test.',
default=2, optional=True)]
def setUp(self):
self.dut = device_utils.CreateDUTInterface()
self.gyroscope = self.dut.gyroscope.GetController()
self.ui = test_ui.UI()
self.template = ui_templates.OneSection(self.ui)
self.ui.AppendCSS(_CSS)
self._task_manager = None
def runTest(self):
task_list = [ReadGyroscopeTask(self, self.gyroscope,
self.args.rotation_threshold,
self.args.stop_threshold,
self.args.timeout_secs,
self.args.setup_time_secs)]
self._task_manager = factory_task.FactoryTaskManager(self.ui, task_list)
self._task_manager.Run()