195 lines
7.0 KiB
Python
195 lines
7.0 KiB
Python
# Copyright (c) 2014 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 re
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.common_lib import utils
|
|
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
|
|
|
|
|
|
class firmware_Mosys(FirmwareTest):
|
|
"""
|
|
Mosys commands test for Firmware values.
|
|
|
|
Execute
|
|
* mosys -k ec info
|
|
* mosys platform name
|
|
* mosys -k pd info
|
|
|
|
"""
|
|
version = 1
|
|
|
|
|
|
def initialize(self, host, cmdline_args, dev_mode=False):
|
|
# Parse arguments from command line
|
|
dict_args = utils.args_to_dict(cmdline_args)
|
|
super(firmware_Mosys, self).initialize(host, cmdline_args)
|
|
self.switcher.setup_mode('dev' if dev_mode else 'normal')
|
|
# a list contain failed execution.
|
|
self.failed_command = []
|
|
# Get a list of available mosys commands.
|
|
lines = self.run_cmd('mosys help')
|
|
self.command_list = []
|
|
cmdlist_start = False
|
|
for line in lines:
|
|
if cmdlist_start:
|
|
cmdlst = re.split('\s+', line)
|
|
if len(cmdlst) > 2:
|
|
self.command_list.append(cmdlst[1])
|
|
elif 'Commands:' in line:
|
|
cmdlist_start = True
|
|
logging.info('Available commands: %s', ' '.join(self.command_list))
|
|
|
|
def check_for_errors(self, output, command):
|
|
"""
|
|
Check for known errors.
|
|
1. Bad system call (core dumped)
|
|
We see this a lot now that mosys is in a minijail. Even if we see
|
|
this error, mosys will return success, so we need to check stderr.
|
|
"""
|
|
for line in output:
|
|
if "Bad system call" in line:
|
|
logging.info("ERROR: Bad system call detected when calling mosys!")
|
|
self._tag_failure(command)
|
|
return 1
|
|
return 0
|
|
|
|
def run_cmd(self, command):
|
|
"""
|
|
Log and execute command and return the output.
|
|
|
|
@param command: Command to execution device.
|
|
@returns the output of command.
|
|
|
|
"""
|
|
logging.info('Execute %s', command)
|
|
output = self.faft_client.system.run_shell_command_get_output(
|
|
command, True)
|
|
logging.info('Output %s', output)
|
|
return output
|
|
|
|
def check_ec_version(self, command, exp_ec_version):
|
|
"""
|
|
Compare output of 'ectool version' for the current firmware
|
|
copy to exp_ec_version.
|
|
|
|
@param command: command string
|
|
@param exp_ec_version: The expected EC version string.
|
|
|
|
"""
|
|
lines = self.run_cmd('ectool version')
|
|
fwcopy_pattern = re.compile('Firmware copy: (.*)$')
|
|
ver_pattern = re.compile('(R[OW]) version: (.*)$')
|
|
version = {}
|
|
for line in lines:
|
|
ver_matched = ver_pattern.match(line)
|
|
if ver_matched:
|
|
version[ver_matched.group(1)] = ver_matched.group(2)
|
|
fwcopy_matched = fwcopy_pattern.match(line)
|
|
if fwcopy_matched:
|
|
fwcopy = fwcopy_matched.group(1)
|
|
if fwcopy in version:
|
|
actual_version = version[fwcopy]
|
|
logging.info('Expected ec version %s actual_version %s',
|
|
exp_ec_version, actual_version)
|
|
if exp_ec_version != actual_version:
|
|
self._tag_failure(command)
|
|
else:
|
|
self._tag_failure(command)
|
|
logging.error('Failed to locate version from ectool')
|
|
|
|
def check_pd_version(self, command, exp_pd_version):
|
|
"""
|
|
Compare output of 'ectool --dev 1 version' for the current PD firmware
|
|
copy to exp_pd_version.
|
|
|
|
@param command: command string
|
|
@param exp_pd_version: The expected PD version string.
|
|
|
|
"""
|
|
lines = self.run_cmd('ectool --dev 1 version')
|
|
fwcopy_pattern = re.compile('Firmware copy: (.*)$')
|
|
ver_pattern = re.compile('(R[OW]) version: (.*)$')
|
|
version = {}
|
|
for line in lines:
|
|
ver_matched = ver_pattern.match(line)
|
|
if ver_matched:
|
|
version[ver_matched.group(1)] = ver_matched.group(2)
|
|
fwcopy_matched = fwcopy_pattern.match(line)
|
|
if fwcopy_matched:
|
|
fwcopy = fwcopy_matched.group(1)
|
|
if fwcopy in version:
|
|
actual_version = version[fwcopy]
|
|
logging.info('Expected pd version %s actual_version %s',
|
|
exp_pd_version, actual_version)
|
|
if exp_pd_version != actual_version:
|
|
self._tag_failure(command)
|
|
else:
|
|
self._tag_failure(command)
|
|
logging.error('Failed to locate version from ectool')
|
|
|
|
def _tag_failure(self, cmd):
|
|
self.failed_command.append(cmd)
|
|
logging.error('Execute %s failed', cmd)
|
|
|
|
def run_once(self, dev_mode=False):
|
|
"""Runs a single iteration of the test."""
|
|
# mosys -k ec info
|
|
command = 'mosys -k ec info'
|
|
if self.faft_config.chrome_ec:
|
|
output = self.run_cmd(command)
|
|
self.check_for_errors(output, command)
|
|
p = re.compile(
|
|
'vendor="[A-Z]?[a-z]+" name="[ -~]+" fw_version="(.*)"')
|
|
v = p.match(output[0])
|
|
if v:
|
|
version = v.group(1)
|
|
self.check_ec_version(command, version)
|
|
else:
|
|
self._tag_failure(command)
|
|
else:
|
|
logging.info('Skip "%s", command not available.', command)
|
|
|
|
# mosys platform name
|
|
command = 'mosys platform name'
|
|
output = self.run_cmd(command)
|
|
self.check_for_errors(output, command)
|
|
|
|
# mosys -k pd info
|
|
command = 'mosys -k pd info'
|
|
if self.faft_config.chrome_usbpd and 'pd' in self.command_list:
|
|
output = self.run_cmd(command)
|
|
self.check_for_errors(output, command)
|
|
p = re.compile('vendor="[a-z]+" name="[ -~]+" fw_version="(.*)"')
|
|
v = p.match(output[0])
|
|
if v:
|
|
version = v.group(1)
|
|
self.check_pd_version(command, version)
|
|
else:
|
|
self._tag_failure(command)
|
|
else:
|
|
logging.info('Skip "%s", command not available.', command)
|
|
|
|
# mosys -k memory spd print all (check no error output)
|
|
command = 'mosys -k memory spd print all'
|
|
output = self.run_cmd(command)
|
|
self.check_for_errors(output, command)
|
|
p = re.compile('^dimm=".*$')
|
|
# Each line should start with "dimm=".
|
|
for i in output:
|
|
if not p.match(i):
|
|
logging.error('output does not start with dimm=%s', i)
|
|
self._tag_failure(command)
|
|
break
|
|
|
|
# Add any other mosys commands or tests before this section.
|
|
# empty failed_command indicate all passed.
|
|
if self.failed_command:
|
|
raise error.TestFail('%d commands failed, detail above. '
|
|
'Failed commands are "%s"' %
|
|
(len(self.failed_command),
|
|
','.join(self.failed_command)))
|