blob: 0bc2932014c2d398e166699b168abc3a015188a5 [file] [log] [blame]
# 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.
"""Setup device data from VPD (Vital Product Data).
Description
-----------
Device Data (``cros.factory.test.device_data``) maintains the data during
manufacturing flow, and will be wiped when device goes to shipping mode (or
re-flashed for re-run of manufacturing flow).
To rebuild device data, we may want to schedule few ``write_device_data_to_vpd``
invocations in manufacturing flow, and one ``read_device_data_from_vpd`` in
beginning of test list to get the data back when a device has been wiped for
re-run.
This test reads VPD values from specified argument ``ro_key_map`` and
``rw_key_map``, which are mappings from VPD names to device data keys. For
example::
{'foo': 'bar.baz'}
This map indicates we have to read ``foo`` from VPD and write to device data
using key ``bar.baz``. If VPD name ends with "*", then all keys with the prefix
will be added to device data. For example::
{'foo.*': 'bar'}
This map indicates we will read all VPD values starting with ``foo.`` and store
in VPD as ``bar.*``. In other words, VPD entry ``foo.region`` will become
``bar.region`` in device data.
``rw_key_map`` works in similar way, except it's reading values from RW VPD.
If the specified VPD keys don't exist, the test will still pass without
warnings.
The default is to read only ``{'factory.*': 'factory'}`` in ``rw_key_map``,
device serial number (serial_number) and mainboard serial number
(mlb_serial_number).
Test Procedure
--------------
This is an automated test without user interaction.
Start the test and the specified device data values will be fetched from VPD
and then written to device data.
Dependency
----------
This test relies on ``vpd`` component in Device API to access VPD.
Examples
--------
To read standard manufacturing information from VPD, add this in test list::
{
"pytest_name": "read_device_data_from_vpd"
}
To write and read back component data into VPD, add this in test list::
{
"pytest_name": "write_device_data_to_vpd",
"args": {
"rw_key_map": {
"component.*": "component"
}
}
}
... (reboot) ...
{
"pytest_name": "read_device_data_from_vpd",
"args": {
"rw_key_map": {
"component.*": "component"
}
}
}
"""
import factory_common # pylint: disable=unused-import
from cros.factory.device import device_utils
from cros.factory.test import device_data
from cros.factory.test.i18n import _
from cros.factory.test import test_case
from cros.factory.utils.arg_utils import Arg
class ReadDeviceDataFromVPD(test_case.TestCase):
ARGS = [
Arg('ro_key_map', dict,
'Mapping of (VPD_NAME, DEVICE_DATA_KEY) to read from RO VPD.',
default=None),
Arg('rw_key_map', dict,
'Mapping of (VPD_NAME, DEVICE_DATA_KEY) to read from RW VPD.',
default=None),
]
def setUp(self):
self.dut = device_utils.CreateDUTInterface()
def runTest(self):
sections = {
'ro': self.args.ro_key_map,
'rw': self.args.rw_key_map
}
if sections['ro'] is None and sections['rw'] is None:
sections['ro'] = device_data.DEFAULT_RO_VPD_KEY_MAP
sections['rw'] = device_data.DEFAULT_RW_VPD_KEY_MAP
for name, key_map in sections.iteritems():
self.ui.SetState(
_('Reading device data from {vpd_section} VPD...',
vpd_section=name.upper()))
if not key_map:
continue
vpd = getattr(self.dut.vpd, name)
device_data.UpdateDeviceDataFromVPD({name: key_map}, {name: vpd.GetAll()})