blob: 1fee0557b1f5bdc45211368fb7c8abfb12f5d780 [file] [log] [blame]
# Copyright 2017 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
from autotest_lib.server.cros.servo import chrome_ti50
class firmware_Cr50Testlab(Cr50Test):
"""Verify cr50 testlab enable/disable."""
version = 1
ACCESS_DENIED = 'Access Denied'
INVALID_PARAM = 'Parameter 1 invalid'
BASIC_ERROR = 'Usage: ccd '
def initialize(self, host, cmdline_args, full_args):
"""Initialize servo. Check that it can access cr50"""
if host.servo.main_device_is_ccd():
raise error.TestNAError('Use a flex cable instead of CCD cable.')
super(firmware_Cr50Testlab, self).initialize(host, cmdline_args,
full_args)
if not hasattr(self, 'gsc'):
raise error.TestNAError('Test can only be run on devices with '
'access to the GSC console')
if isinstance(self.gsc, chrome_ti50.ChromeTi50):
self.BASIC_ERROR = 'Command \'ccd\' failed'
self.INVALID_PARAM = 'Param2'
# 'ecrst pulse' is always available. This test is going to lock ccd.
# use 'ecrst pulse' for cold reset, so the test can enter dev mode
# when ccd is locked.
if (self.servo.has_control('gsc_ecrst_pulse')
and self.servo.has_control('cold_reset_select')):
logging.info('Using ecrst pulse for cold reset')
self.servo.set('cold_reset_select', 'gsc_ecrst_pulse')
elif (self.servo.main_device_uses_gsc_drv()
and self.gsc.running_mp_image()):
# TODO(b/294426380): remove this after servod has support for
# using `ecrst pulse` in the lab.
raise error.TestNAError('Uses gsc for ecrst. Cannot run until '
'cold_reset issue is resolved')
# Get the current reset count, so we can check that there haven't been
# any cr50 resets at any point during the test.
self.start_reset_count = self.gsc.get_reset_count()
def cleanup(self):
"""Reenable testlab mode."""
try:
self.fast_ccd_open(enable_testlab=True)
finally:
super(firmware_Cr50Testlab, self).cleanup()
def try_testlab(self, mode, err=''):
"""Try to modify ccd testlab mode.
Args:
mode: The testlab command: 'on', 'off', or 'open'
err: An empty string if the command should succeed or the error
message.
Raises:
TestFail if setting the ccd testlab mode doesn't match err
"""
logging.info('Setting ccd testlab %s', mode)
rv = self.gsc.send_command_get_output('ccd testlab %s' % mode,
['ccd.*>'])[0]
logging.info(rv)
if err not in rv or (not err and self.BASIC_ERROR in rv):
raise error.TestFail('Unexpected result setting "%s": %r' % (mode,
rv))
if err:
return
if mode == 'open':
if mode != self.gsc.get_ccd_level():
raise error.TestFail('ccd testlab open did not open the device')
else:
self.gsc.run_pp(self.gsc.PP_SHORT)
if (mode == 'on') != self.gsc.testlab_is_on():
raise error.TestFail('Testlab mode could not be turned %s' %
mode)
logging.info('Set ccd testlab %s', mode)
def check_reset_count(self):
"""Verify there haven't been any cr50 reboots"""
reset_count = self.gsc.get_reset_count()
if self.start_reset_count != reset_count:
raise error.TestFail('Unexpected cr50 reboot')
def reset_ccd(self):
"""Enable ccd testlab mode and set the privilege level to open"""
logging.info('Resetting CCD state')
self.fast_ccd_open(enable_testlab=True, reset_ccd=True)
self.check_reset_count()
def run_once(self):
"""Try to set testlab mode from different privilege levels."""
# Bogus isn't a valid mode. Make sure it fails
self.reset_ccd()
self.try_testlab('bogus', err=self.INVALID_PARAM)
# CCD can be opened without physical presence if testlab mode is enabled
self.reset_ccd()
self.try_testlab('on')
self.try_testlab('open')
self.check_reset_count()
# You shouldn't be able to use testlab open if it is disabled
self.reset_ccd()
self.try_testlab('off')
self.try_testlab('open', err=self.ACCESS_DENIED)
self.check_reset_count()
# You can't turn on testlab mode while ccd is locked
self.reset_ccd()
self.gsc.set_ccd_level('lock')
self.try_testlab('on', err=self.ACCESS_DENIED)
self.check_reset_count()
# You can't turn off testlab mode while ccd is locked
self.reset_ccd()
self.gsc.set_ccd_level('lock')
self.try_testlab('off', err=self.ACCESS_DENIED)
self.check_reset_count()
# If testlab mode is enabled, you can open the device without physical
# presence by using 'ccd testlab open'.
self.reset_ccd()
self.try_testlab('on')
self.gsc.set_ccd_level('lock')
self.try_testlab('open')
self.check_reset_count()
# If testlab mode is disabled, testlab open should fail with access
# denied.
self.reset_ccd()
self.try_testlab('off')
self.gsc.set_ccd_level('lock')
self.try_testlab('open', err=self.ACCESS_DENIED)
self.check_reset_count()
logging.info('ccd testlab is accessible')