xref: /aosp_15_r20/external/autotest/server/site_tests/firmware_InvalidUSB/firmware_InvalidUSB.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright (c) 2011 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 import vboot_constants as vboot
9from autotest_lib.server.cros.faft.firmware_test import ConnectionError
10from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
11
12
13class firmware_InvalidUSB(FirmwareTest):
14    """
15    Servo based booting an invalid USB image test.
16
17    This test requires a USB disk plugged-in, which contains a ChromeOS test
18    image (built by "build_image --test"). On runtime, this test corrupts the
19    USB image and tries to boot into it. A failure is expected. It then
20    restores the USB image and boots into it again.
21    """
22    version = 1
23    NEEDS_SERVO_USB = True
24
25    def restore_usb(self):
26        """Restore the USB image. USB plugs/unplugs happen in this method."""
27        self.servo.switch_usbkey('host')
28        usb_dev = self.servo.probe_host_usb_dev()
29        self.restore_usb_kernel(usb_dev)
30
31    def initialize(self, host, cmdline_args):
32        """Initialize the test"""
33        super(firmware_InvalidUSB, self).initialize(host, cmdline_args)
34        self.setup_usbkey(usbkey=True)
35        self.servo.switch_usbkey('host')
36        usb_dev = self.servo.probe_host_usb_dev()
37        self.assert_test_image_in_usb_disk(usb_dev)
38        self.corrupt_usb_kernel(usb_dev)
39        self.switcher.setup_mode('normal')
40        self.servo.switch_usbkey('dut')
41
42    def cleanup(self):
43        """Cleanup the test"""
44        try:
45            self.restore_usb()
46        except Exception as e:
47            logging.error("Caught exception: %s", str(e))
48        super(firmware_InvalidUSB, self).cleanup()
49
50    def run_once(self):
51        """Main test logic"""
52        logging.info("Turn on the recovery boot. Remove and insert the"
53                     "corrupted USB stick, a boot failure is expected."
54                     "Restore the USB image and boot it again.")
55        self.check_state((self.checkers.crossystem_checker, {
56                          'devsw_boot': '0',
57                          'mainfw_type': 'normal',
58                          }))
59
60        # Switch servo v4 (if present) as a SNK. Make sure USB key is bootable.
61        self.set_servo_v4_role_to_snk()
62
63        self.switcher.reboot_to_mode(to_mode='rec', wait_for_dut_up=False)
64        logging.info('Wait to ensure the USB image is unable to boot...')
65        try:
66            self.switcher.wait_for_client(
67                    timeout=self.faft_config.usb_image_boot_timeout)
68            raise error.TestFail('Should not boot from the invalid USB image.')
69        except ConnectionError:
70            logging.info(
71                'The USB image is surely unable to boot. Restore it and try...')
72
73        self.restore_usb()
74        self.servo.switch_usbkey('dut')
75        self.switcher.wait_for_client()
76
77        logging.info("Expected to boot the restored USB image and reboot.")
78        self.check_state((self.checkers.crossystem_checker, {
79                          'mainfw_type': 'recovery',
80                          'recovery_reason': vboot.RECOVERY_REASON['RO_MANUAL'],
81                          }))
82        self.switcher.mode_aware_reboot()
83
84        logging.info("Expected to normal boot and done.")
85        self.check_state((self.checkers.crossystem_checker, {
86                          'devsw_boot': '0',
87                          'mainfw_type': 'normal',
88                          }))
89