Home | History | Annotate | Download | only in firmware_DevScreenTimeout
      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 
      5 import logging
      6 import time
      7 
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
     10 
     11 
     12 class firmware_DevScreenTimeout(FirmwareTest):
     13     """
     14     Servo based developer firmware screen timeout test.
     15 
     16     When booting in developer mode, the firmware shows a screen to warn user
     17     the disk image is not secured. If a user press Ctrl-D or a timeout reaches,
     18     it will boot to developer mode. This test is to verify the timeout period.
     19 
     20     This test tries to boot the system in developer mode twice.
     21     The first one will repeatedly press Ctrl-D on booting in order to reduce
     22     the time on developer warning screen. The second one will do nothing and
     23     wait the developer screen timeout. The time difference of these two boots
     24     is close to the developer screen timeout.
     25     """
     26     version = 1
     27 
     28     # We accept 5s timeout margin as we need 5s to ensure client is offline.
     29     # If the margin is too small and firmware initialization is too fast,
     30     # the test will fail incorrectly.
     31     TIMEOUT_MARGIN = 5
     32 
     33     fw_time_record = {}
     34 
     35 
     36     def record_fw_boot_time(self, tag):
     37         """Record the current firmware boot time with the tag.
     38 
     39         @param tag: A tag about this boot.
     40         @raise TestError: If the firmware-boot-time file does not exist.
     41         """
     42         [fw_time] = self.faft_client.system.run_shell_command_get_output(
     43                 'cat /tmp/firmware-boot-time')
     44         logging.info('Got firmware boot time [%s]: %s', tag, fw_time)
     45         if fw_time:
     46             self.fw_time_record[tag] = float(fw_time)
     47         else:
     48             raise error.TestError('Failed to get the firmware boot time.')
     49 
     50     def check_timeout_period(self):
     51         """Check the firmware screen timeout period matches our spec.
     52 
     53         @raise TestFail: If the timeout period does not match our spec.
     54         """
     55         # On tablets/detachables, eliminate the time taken for pressing volume
     56         # down button (HOLD_VOL_DOWN_BUTTON_BYPASS + 0.1) to calculate the
     57         # firmware boot time of quick dev boot.
     58         if self.faft_config.fw_bypasser_type == 'tablet_detachable_bypasser':
     59             self.fw_time_record['quick_bypass_boot'] -= \
     60                             (self.switcher.HOLD_VOL_DOWN_BUTTON_BYPASS + 0.1)
     61             logging.info("Firmware boot time [quick_bypass_boot] after "
     62                          "eliminating the volume down button press time "
     63                          "(%.1f seconds): %s",
     64                          self.switcher.HOLD_VOL_DOWN_BUTTON_BYPASS + 0.1,
     65                          self.fw_time_record['quick_bypass_boot'])
     66         got_timeout = (self.fw_time_record['timeout_boot'] -
     67                        self.fw_time_record['quick_bypass_boot'])
     68         logging.info('Estimated developer firmware timeout: %s', got_timeout)
     69 
     70         if (abs(got_timeout - self.faft_config.dev_screen_timeout) >
     71                 self.TIMEOUT_MARGIN):
     72             raise error.TestFail(
     73                     'The developer firmware timeout does not match our spec: '
     74                     'expected %.2f +/- %.2f but got %.2f.' %
     75                     (self.faft_config.dev_screen_timeout, self.TIMEOUT_MARGIN,
     76                      got_timeout))
     77 
     78     def initialize(self, host, cmdline_args):
     79         super(firmware_DevScreenTimeout, self).initialize(host, cmdline_args)
     80         # NA error check point for this test
     81         if (self.faft_config.fw_bypasser_type != 'ctrl_d_bypasser' and
     82                 self.faft_config.fw_bypasser_type != 'tablet_detachable_bypasser'):
     83             raise error.TestNAError("This test is only valid on devices with "
     84                                     "screens.")
     85         # This test is run on developer mode only.
     86         self.switcher.setup_mode('dev')
     87         self.setup_usbkey(usbkey=False)
     88 
     89     def run_once(self):
     90         logging.info("Always expected developer mode firmware A boot.")
     91         self.check_state((self.checkers.crossystem_checker, {
     92                               'devsw_boot': '1',
     93                               'mainfw_act': 'A',
     94                               'mainfw_type': 'developer',
     95                               }))
     96 
     97         # To add an extra reboot before the measurement
     98         # to avoid TPM reset too long
     99         self.switcher.simple_reboot()
    100         self.switcher.wait_for_client()
    101         logging.info("Reboot and bypass the Developer warning screen "
    102                      "immediately.")
    103         self.switcher.simple_reboot()
    104         self.switcher.bypass_dev_mode()
    105         self.switcher.wait_for_client()
    106         logging.info("Record the firmware boot time without waiting for "
    107                      "firmware screen.")
    108         self.record_fw_boot_time('quick_bypass_boot')
    109 
    110         logging.info("Reboot the device, do nothing and wait for screen "
    111                      "timeout. And then record the firmware boot time.")
    112         self.switcher.simple_reboot()
    113         self.switcher.wait_for_client()
    114         # Record the boot time of firmware screen timeout.
    115         self.record_fw_boot_time('timeout_boot')
    116 
    117         logging.info("Check the firmware screen timeout matches our spec.")
    118         self.check_timeout_period()
    119