Home | History | Annotate | Download | only in platform_RebootAfterUpdate
      1 # Copyright (c) 2013 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 import autotest, test
     10 from autotest_lib.server.cros import autoupdate_utils
     11 
     12 
     13 class platform_RebootAfterUpdate(test.test):
     14     """Test that updates the machine, reboots, and logs in / logs out.
     15 
     16     This test keeps a reboot timeout in order to keep the system boot times
     17     regressing in performance. For example, if Chrome takes a long time to
     18     shutdown / hangs, other tests have much longer timeouts (to prevent them
     19     from being flaky) while this test targets these hangs. Note, this test only
     20     has smaller timeouts for boot, not for login/logout. Also, these timeouts
     21     are still fairly conservative and are only meant to catch large regressions
     22     or hangs, not small regressions.
     23 
     24     """
     25     version = 1
     26 
     27     _REBOOT_ERROR_MESSAGE = (
     28             'System failed to restart within the timeout after '
     29             '%(reason)s. This failure indicates that the system after '
     30             'receiving a reboot request and restarting did not '
     31             'reconnect via ssh within the timeout. Actual time %(actual)d '
     32             'seconds vs expected time: %(expected)d seconds')
     33 
     34     # Timeouts specific to this test. These should be as low as possible.
     35 
     36     # Total amount of time to wait for a reboot to return.
     37     _REBOOT_TIMEOUT = 120
     38 
     39 
     40     @classmethod
     41     def reboot_with_timeout(cls, host, reason):
     42         """Reboots the device and checks to see if it completed within desired.
     43 
     44         @param host: Autotest host object to reboot.
     45         @param reason: string representing why we are rebooting e.g. autoupdate.
     46 
     47         Raises:
     48             error.TestFail: If it takes too long to reboot.
     49         """
     50         start_time = time.time()
     51         host.reboot()
     52         reboot_duration = time.time() - start_time
     53         if reboot_duration > cls._REBOOT_TIMEOUT:
     54             raise error.TestFail(
     55                 cls._REBOOT_ERROR_MESSAGE % dict(
     56                         reason=reason, actual=reboot_duration,
     57                         expected=cls._REBOOT_TIMEOUT))
     58 
     59 
     60     def run_once(self, host, job_repo_url=None):
     61         """Runs the test.
     62 
     63         @param host: a host object representing the DUT
     64         @param job_repo_url: URL to get the image.
     65 
     66         @raise error.TestError if anything went wrong with setting up the test;
     67                error.TestFail if any part of the test has failed.
     68 
     69         """
     70         updater = autoupdate_utils.get_updater_from_repo_url(host, job_repo_url)
     71         updater.update_stateful(clobber=True)
     72 
     73         logging.info('Rebooting after performing update.')
     74         self.reboot_with_timeout(host, 'update')
     75 
     76         # TODO(sosa): Ideally we would be able to just use
     77         # autotest.run_static_method to login/logout, however, this
     78         # functionality is currently nested deep into the test logic. Once
     79         # telemetry has replaced pyauto login and has been librarized, we
     80         # should switch to using that code and not have to rely on running a
     81         # client test to do what we want.
     82         logging.info('Running sanity desktop login to see that we can '
     83                      'login and logout after performing an update.')
     84         client_at = autotest.Autotest(host)
     85         self.job.set_state('client_success', False)
     86         client_at.run_test('login_LoginSuccess')
     87         if not self.job.get_state('client_success'):
     88             raise error.TestFail(
     89                     'Failed to login successfully after an update.')
     90 
     91         logging.info('Rebooting the DUT after first login/logout.')
     92         self.reboot_with_timeout(host, 'first login')
     93