1# Copyright (c) 2015 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 6import time 7import re 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.server.cros import vboot_constants as vboot 12from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 13 14 15class firmware_FastbootErase(FirmwareTest): 16 """ 17 Testing Erase functionality in Fastboot 18 Will erase the kernel, causing the DUT to 19 boot into recovery mode. Then restores the 20 kernel. 21 22 This needs to be only enabled for Android tests. 23 """ 24 version = 1 25 26 KERNEL_TMP_FILE = '/tmp/android_kernel' 27 28 def initialize(self, host, cmdline_args, dev_mode=False): 29 super(firmware_FastbootErase, self).initialize(host, cmdline_args) 30 self.switcher.setup_mode('dev' if dev_mode else 'normal') 31 # set flags so that we can do the erase command 32 self.clear_set_gbb_flags(0, 33 vboot.GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP) 34 35 def cleanup(self): 36 """Restore the gbb flags""" 37 self.clear_set_gbb_flags(vboot.GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP, 38 0) 39 super(firmware_FastbootErase, self).cleanup() 40 41 def is_recovery_mode(self): 42 """Check if DUT in recovery mode 43 44 Unfortunately, adb get-state just returns "unknown" 45 so need to do it with adb devices and regexp 46 """ 47 result = self.faft_client.host.run_shell_command_get_output( 48 'adb devices') 49 if 'recovery' in result[1]: 50 return True 51 else: 52 return False 53 54 def wait_for_client_recovery(self, timeout=300): 55 """Blocks until detects that DUT is in recovery mode""" 56 utils.wait_for_value(self.is_recovery_mode, True, timeout_sec=timeout) 57 58 def run_once(self, dev_mode=False): 59 if not self.faft_client.system.has_host(): 60 raise error.TestNAError('DUT is not Android device. Skipping test') 61 62 # first copy out kernel partition 63 logging.info("Making copy of kernel") 64 self.faft_client.host.run_shell_command( 65 'adb pull /dev/block/mmcblk0p1 %s' % self.KERNEL_TMP_FILE) 66 67 # now erase boot partition 68 self.faft_client.host.run_shell_command('adb reboot bootloader') 69 self.switcher.wait_for_client_fastboot() 70 71 if not self.switcher.is_fastboot_mode(): 72 raise error.TestFail("DUT not in fastboot mode!") 73 74 logging.info("Erasing the kernel") 75 self.faft_client.host.run_shell_command('fastboot erase kernel') 76 self.faft_client.host.run_shell_command('fastboot continue') 77 78 # DUT should enter into recovery OS 79 self.wait_for_client_recovery() 80 81 # Push the volume down button to "Reboot to bootloader" 82 # and select it with the power button 83 self.servo.volume_down() 84 self.servo.power_key(self.faft_config.hold_pwr_button_poweron) 85 self.switcher.wait_for_client_fastboot() 86 87 # Should be in recovery mode. 88 # Reflash the kernel image that we saved earlier 89 logging.info("Repairing the kernel") 90 self.faft_client.host.run_shell_command( 91 'fastboot flash kernel %s' % self.KERNEL_TMP_FILE) 92 self.faft_client.host.run_shell_command( 93 'fastboot continue') 94 95 self.switcher.wait_for_client() 96 97 # cleaning up the temp file 98 self.faft_client.host.run_shell_command( 99 'rm %s' % self.KERNEL_TMP_FILE) 100