blob: 122a364e8de3b1244d39c5732f7fdfb0e95cc934 [file] [log] [blame]
# Copyright 2018 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from __future__ import print_function
import logging
import time
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
class firmware_Cr50Open(Cr50Test):
"""Verify cr50 open."""
version = 1
DEEP_SLEEP_DELAY = 20
def initialize(self, host, cmdline_args, ccd_open_restricted, full_args):
"""Initialize the test"""
if not host.servo:
raise error.TestNAError('Test requires servo.')
# Test needs to control the GSC power button input.
if not host.servo.main_device_is_flex():
raise error.TestNAError('Run with c2d2 or servo micro.')
super(firmware_Cr50Open, self).initialize(host, cmdline_args,
full_args)
if not self.faft_config.has_powerbutton:
raise error.TestNAError('No power button. Unable to test ccd open')
self.ccd_open_restricted = ccd_open_restricted
self.fast_ccd_open(enable_testlab=True)
self.gsc.ccd_reset()
self.gsc.set_ccd_level('lock')
def wait_ap_reboot(self, old_boot_id):
"""Wait for AP reboot after ccd open."""
time.sleep(15)
# CCD open should cause an AP reboot, so boot_id should change.
# test_wait_for_boot will check this.
self.host.test_wait_for_boot(old_boot_id)
def check_cr50_open(self, dev_mode, batt_pres):
"""Verify you can't open ccd unless dev mode is enabled.
Make sure the ability to open ccd corresponds with the device being in
dev mode. When the device is in dev mode, open should be accessible from
the AP. When the device is in normal mode it shouldn't be accessible.
Open will never work from the console.
Args:
dev_mode: bool reflecting whether the device is in dev mode. If
True, the device is in dev mode. If False, the device is in
normal mode.
batt_pres: True if the battery is connected
"""
self.gsc.set_ccd_level('lock')
self.gsc.get_ccd_info()
#Make sure open doesn't work from the console.
logging.info('ccd open from console')
try:
boot_id = self.host.get_boot_id()
self.gsc.set_ccd_level('open')
self.wait_ap_reboot(boot_id)
except error.TestFail as e:
self.gsc.check_for_console_errors('ccd open from console')
if not batt_pres:
raise error.TestFail('Unable to open cr50 from console with '
'batt disconnected: %s' % str(e))
# If ccd open is limited, open should fail with access denied
#
# TODO: move logic to set_ccd_level.
if 'Access Denied' in str(e) and self.ccd_open_restricted:
logging.info('console ccd open successfully rejected')
else:
raise
else:
if self.ccd_open_restricted and batt_pres:
raise error.TestFail('Open should not be accessible from the '
'console')
self.gsc.set_ccd_level('lock')
if not batt_pres:
logging.info('ccd open from AP (batt disconnected)')
boot_id = self.host.get_boot_id()
cr50_utils.GSCTool(self.host, ['-a', '-o'],
expect_reboot=not batt_pres)
self.wait_ap_reboot(boot_id)
if self.gsc.OPEN != self.gsc.get_ccd_level():
raise error.TestFail('Unable to open cr50 from AP with batt '
'disconnected')
return
#Make sure open only works from the AP when the device is in dev mode.
logging.info('ccd open from AP')
try:
boot_id = self.host.get_boot_id()
self.ccd_open_from_ap()
self.wait_ap_reboot(boot_id)
except error.TestFail as e:
logging.info(e)
self.gsc.check_for_console_errors('ccd open from ap')
# ccd open should work if the device is in dev mode or ccd open
# isn't restricted. If open failed for some reason raise the error.
if dev_mode or not self.ccd_open_restricted:
raise
def run_once(self):
"""Check open only works when the device is in dev mode."""
self.gsc.send_command('ccd testlab open')
self.gsc.set_batt_pres_state('connected', True)
self.switcher.reboot_to_mode(to_mode='dev')
logging.info('check open in dev mode, battery connected')
self.check_cr50_open(True, True)
self.switcher.reboot_to_mode(to_mode='normal')
logging.info('check open in normal mode, battery connected')
self.check_cr50_open(False, True)
self.gsc.send_command('ccd testlab open')
self.gsc.set_batt_pres_state('disconnected', True)
logging.info('check open in normal mode, battery disconnected')
self.check_cr50_open(False, False)
self.gsc.send_command('ccd testlab open')
self.gsc.ccd_disable()
# Verify ccd open survives deep sleep.
logging.info('check deep sleep')
start_ds_count = self.gsc.get_deep_sleep_count()
self.faft_client.system.run_shell_command('poweroff', True)
utils.wait_for_value(self.gsc.ap_is_on, False)
time.sleep(self.DEEP_SLEEP_DELAY)
if start_ds_count == self.gsc.get_deep_sleep_count():
raise error.TestNAError('Unable to enter deep sleep')
if self.gsc.OPEN != self.gsc.get_ccd_level():
raise error.TestFail('Open cleared after deep sleep')
# Verify ccd open is cleared after a hard reset.
logging.info('check reboot')
self.gsc.reboot()
if self.gsc.OPEN == self.gsc.get_ccd_level():
raise error.TestFail('Open survived hard reset')