• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021 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
7
8from autotest_lib.server import test
9from autotest_lib.server.hosts import cros_firmware
10from autotest_lib.client.common_lib import error
11
12
13class fleet_FirmwareUpdate(test.test):
14    """Test to update OS bundled firmware and validate DUT is in good state."""
15    version = 1
16
17    UPDATE_CMD = "/usr/sbin/chromeos-firmwareupdate --wp=1 --mode=autoupdate"
18
19    def update_os_bundled_firmware(self, host):
20        """Update OS bundled firmware, RW only.
21
22        Args:
23          host: Target host machine to update firmware.
24
25        raises:
26          error.TestFail if update firmware cmd return with non-zero code.
27        """
28        logging.info("Starting update firmware on %s.", host.hostname)
29        try:
30            res = host.run(self.UPDATE_CMD)
31        except:
32            raise error.TestFail("Failed to update firmware.")
33
34    def pre_update_validation(self, host):
35        """Validate DUT is in good state before firmware update.
36
37        Args:
38          host: Target host machine to do the validation.
39
40        raises:
41          error.TestNAError if DUT is not sshable, or not come back after
42                            reboot.
43        """
44        # Ensure the DUT is sshable before firmware update.
45        if not host.is_up():
46            raise error.TestNAError("DUT is down before firmware update.")
47
48        # Ensure the DUT can reboot normally before firmware update.
49        logging.info("Rebooting %s prior firmware update", host.hostname)
50        try:
51            host.reboot(timeout=host.BOOT_TIMEOUT, wait=True)
52        except Exception as e:
53            logging.error(e)
54            raise error.TestNAError("DUT failed to reboot before firmware"
55                                    " update.")
56
57    def is_firmware_updated(self, host):
58        """Check whether the DUT is updated to OS bundled firmware.
59
60        Args:
61          host: Target host machine to check.
62        """
63        model = host.get_platform()
64        expected = cros_firmware._get_available_firmware(host, model)
65        if not expected:
66            logging.info("Couldn't get expected version based on model"
67                         " info, skip firmware version check.")
68        actual = host.run("crossystem fwid").stdout
69        logging.debug("Expected firmware: %s, actual firmware on DUT: %s.",
70                      expected, actual)
71        return expected == actual
72
73    def post_update_validation(self, host):
74        """Validate DUT is good after firmware update.
75
76        Args:
77          host: Target host machine to do the validation.
78
79        raises:
80          error.TestFail if the DUT failed to pass validation.
81        """
82        try:
83            host.reboot(timeout=host.BOOT_TIMEOUT, wait=True)
84        except Exception as e:
85            logging.error(e)
86            raise error.TestFail("DUT didn't come back from reboot after"
87                                 " firmware update.")
88        if not self.is_firmware_updated(host):
89            raise error.TestFail("Firmware on DUT mismatch with OS bundled"
90                                 " firmware after update.")
91
92    def run_once(self, host):
93        """Main control of test steps:
94
95        1. Pre-update validation, ensure the DUT is in good state before actual
96           test to reduce flakiness.
97        2. Firmware update, update os bundled firmware in RW portion.
98        3. Post-update validation, test if the DUT is still in good state after
99           receive firmware update.
100        """
101        self.pre_update_validation(host)
102        # Need to wait for machine fully ready for firmware update to reduce
103        # flakiness.
104        time.sleep(60)
105        if self.is_firmware_updated(host):
106            raise error.TestNAError("Firmware version on the DUT is already"
107                                    " up-to-date.")
108        self.update_os_bundled_firmware(host)
109        self.post_update_validation(host)
110