1# Copyright 2017 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.server.cros.faft.cr50_test import Cr50Test 9 10 11class firmware_Cr50Testlab(Cr50Test): 12 """Verify cr50 testlab enable/disable.""" 13 version = 1 14 ACCESS_DENIED = 'Access Denied' 15 INVALID_PARAM = 'Parameter 1 invalid' 16 BASIC_ERROR = 'Usage: ccd ' 17 18 def initialize(self, host, cmdline_args, full_args): 19 """Initialize servo. Check that it can access cr50""" 20 super(firmware_Cr50Testlab, self).initialize(host, cmdline_args, 21 full_args) 22 23 if not hasattr(self, 'cr50'): 24 raise error.TestNAError('Test can only be run on devices with ' 25 'access to the Cr50 console') 26 if self.cr50.using_ccd(): 27 raise error.TestNAError('Use a flex cable instead of CCD cable.') 28 29 if not self.cr50.has_command('ccdstate'): 30 raise error.TestNAError('Cannot test on Cr50 with old CCD version') 31 32 # Get the current reset count, so we can check that there haven't been 33 # any cr50 resets at any point during the test. 34 self.start_reset_count = self.servo.get('cr50_reset_count') 35 36 37 def try_testlab(self, mode, err=''): 38 """Try to modify ccd testlab mode. 39 40 Args: 41 mode: The testlab command: 'on', 'off', or 'open' 42 err: An empty string if the command should succeed or the error 43 message. 44 45 Raises: 46 TestFail if setting the ccd testlab mode doesn't match err 47 """ 48 logging.info('Setting ccd testlab %s', mode) 49 rv = self.cr50.send_command_get_output('ccd testlab %s' % mode, 50 ['ccd.*>'])[0] 51 logging.info(rv) 52 if err not in rv or (not err and self.BASIC_ERROR in rv): 53 raise error.TestFail('Unexpected result setting "%s": %r' % (mode, 54 rv)) 55 if err: 56 return 57 58 if mode == 'open': 59 if mode != self.cr50.get_ccd_level(): 60 raise error.TestFail('ccd testlab open did not open the device') 61 else: 62 self.cr50.run_pp(self.cr50.PP_SHORT) 63 if (mode == 'on') != self.cr50.testlab_is_on(): 64 raise error.TestFail('Testlab mode could not be turned %s' % 65 mode) 66 logging.info('Set ccd testlab %s', mode) 67 68 69 def check_reset_count(self): 70 """Verify there haven't been any cr50 reboots""" 71 reset_count = self.servo.get('cr50_reset_count') 72 if self.start_reset_count != reset_count: 73 raise error.TestFail('Unexpected cr50 reboot') 74 75 76 def reset_ccd(self): 77 """Enable ccd testlab mode and set the privilege level to open""" 78 logging.info('Resetting CCD state') 79 # If testlab mode is enabled, use that to open ccd. It is a lot faster. 80 if self.cr50.testlab_is_on(): 81 self.try_testlab('open') 82 else: 83 self.enter_mode_after_checking_tpm_state('dev') 84 self.ccd_open_from_ap() 85 self.try_testlab('on') 86 self.check_reset_count() 87 88 89 def run_once(self): 90 """Try to set testlab mode from different privilege levels.""" 91 # Dummy isn't a valid mode. Make sure it fails 92 self.reset_ccd() 93 self.try_testlab('dummy', err=self.INVALID_PARAM) 94 95 # If ccd is locked, ccd testlab dummy should fail with access denied not 96 # invalid param. 97 self.reset_ccd() 98 self.cr50.set_ccd_level('lock') 99 self.try_testlab('dummy', err=self.ACCESS_DENIED) 100 101 # CCD can be opened without physical presence if testlab mode is enabled 102 self.reset_ccd() 103 self.try_testlab('on') 104 self.try_testlab('open') 105 self.check_reset_count() 106 107 # You shouldn't be able to use testlab open if it is disabled 108 self.reset_ccd() 109 self.try_testlab('off') 110 self.try_testlab('open', err=self.ACCESS_DENIED) 111 self.check_reset_count() 112 113 # You can't turn on testlab mode while ccd is locked 114 self.reset_ccd() 115 self.cr50.set_ccd_level('lock') 116 self.try_testlab('on', err=self.ACCESS_DENIED) 117 self.check_reset_count() 118 119 # You can't turn off testlab mode while ccd is locked 120 self.reset_ccd() 121 self.cr50.set_ccd_level('lock') 122 self.try_testlab('off', err=self.ACCESS_DENIED) 123 self.check_reset_count() 124 125 # If testlab mode is enabled, you can open the device without physical 126 # presence by using 'ccd testlab open'. 127 self.reset_ccd() 128 self.try_testlab('on') 129 self.cr50.set_ccd_level('lock') 130 self.try_testlab('open') 131 self.check_reset_count() 132 133 # If testlab mode is disabled, testlab open should fail with access 134 # denied. 135 self.reset_ccd() 136 self.try_testlab('off') 137 self.cr50.set_ccd_level('lock') 138 self.try_testlab('open', err=self.ACCESS_DENIED) 139 self.check_reset_count() 140 logging.info('ccd testlab is accessbile') 141