1# Copyright (c) 2020 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 common 8from autotest_lib.client.common_lib import error 9from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10 11class firmware_RecoveryStress(FirmwareTest): 12 """This test checks the following FAFT hardware requirement: 13 - USB stick is plugged into Servo board, not DUT 14 - Recovery boot with USB stick using power_state:rec 15 - Recovery boot with USB stick using power_state:rec_force_mrc 16 """ 17 version = 1 18 NEEDS_SERVO_USB = True 19 20 REBUILD_CACHE_MSG = "MRC: cache data 'RECOVERY_MRC_CACHE' needs update." 21 FIRMWARE_LOG_CMD = 'cbmem -1' + ' | grep ' + REBUILD_CACHE_MSG[:3] 22 RECOVERY_CACHE_SECTION = 'RECOVERY_MRC_CACHE' 23 24 def initialize(self, host, mode, cmdline_args): 25 super(firmware_RecoveryStress, self).initialize( 26 host, cmdline_args) 27 self.mode = mode 28 if self.mode not in ['rec', 'rec_force_mrc']: 29 raise error.TestFail('Wrong mode given. Not supported for this test.') 30 self.switcher.setup_mode('normal') 31 self.setup_usbkey(usbkey=True, host=False) 32 33 def check_cache_rebuilt(self): 34 """Checks the firmware log to ensure that the recovery cache was rebuilt 35 during recovery boot. 36 37 @return True if cache rebuilt 38 """ 39 logging.info('Checking if cache was rebuilt.') 40 41 return self.faft_client.system.run_shell_command_check_output( 42 self.FIRMWARE_LOG_CMD, self.REBUILD_CACHE_MSG) 43 44 def cache_exist(self): 45 """Checks the firmware log to ensure that the recovery cache exists. 46 47 @return True if cache exists 48 """ 49 logging.info("Checking if device has RECOVERY_MRC_CACHE") 50 51 # If flashrom can read the section, this means it exists. 52 command = ('flashrom -p host -r -i %s:/dev/null' 53 % self.RECOVERY_CACHE_SECTION) 54 return self.faft_client.system.run_shell_command_check_output( 55 command, 'SUCCESS') 56 57 def run_once(self, reboot_iterations=1): 58 """Running recovery boot cycles to ensure booting through 59 USB successful.""" 60 61 logging.info("Check DUT is booting into USB image through recovery mode") 62 63 if self.mode == "rec_force_mrc": 64 if not self.faft_config.rec_force_mrc: 65 raise error.TestNAError('DUT cannot force memory training.') 66 67 elif not self.cache_exist(): 68 raise error.TestNAError('No RECOVERY_MRC_CACHE was found on DUT.') 69 70 for i in range(reboot_iterations): 71 logging.info('======== RUNNING RECOVERY BOOT ITERATION %d/%d ' 72 '========', i+1, reboot_iterations) 73 self.switcher.reboot_to_mode(to_mode=self.mode) 74 self.check_state((self.checkers.crossystem_checker, { 75 'mainfw_type': 'recovery' 76 })) 77 if self.mode == "rec_force_mrc": 78 if not self.check_cache_rebuilt(): 79 raise error.TestFail('Recovery Cache was not rebuilt.') 80 81 logging.info("Simple reboot to boot into internal disk") 82 self.switcher.mode_aware_reboot() 83