blob: 27199babfbedfd56e3fd3cf3e22170bdcb215274 [file] [log] [blame]
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.server import autotest, test
from autotest_lib.server.cros import autoupdate_utils
class platform_RebootAfterUpdate(test.test):
"""Test that updates the machine, reboots, and logs in / logs out.
This test keeps a reboot timeout in order to keep the system boot times
regressing in performance. For example, if Chrome takes a long time to
shutdown / hangs, other tests have much longer timeouts (to prevent them
from being flaky) while this test targets these hangs. Note, this test only
has smaller timeouts for boot, not for login/logout. Also, these timeouts
are still fairly conservative and are only meant to catch large regressions
or hangs, not small regressions.
"""
version = 1
_REBOOT_ERROR_MESSAGE = (
'System failed to restart within the timeout after '
'%(reason)s. This failure indicates that the system after '
'receiving a reboot request and restarting did not '
'reconnect via ssh within the timeout. Actual time %(actual)d '
'seconds vs expected time: %(expected)d seconds')
# Timeouts specific to this test. These should be as low as possible.
# Total amount of time to wait for a reboot to return.
_REBOOT_TIMEOUT = 120
@classmethod
def reboot_with_timeout(cls, host, reason):
"""Reboots the device and checks to see if it completed within desired.
@param host: Autotest host object to reboot.
@param reason: string representing why we are rebooting e.g. autoupdate.
Raises:
error.TestFail: If it takes too long to reboot.
"""
start_time = time.time()
host.reboot()
reboot_duration = time.time() - start_time
if reboot_duration > cls._REBOOT_TIMEOUT:
raise error.TestFail(
cls._REBOOT_ERROR_MESSAGE % dict(
reason=reason, actual=reboot_duration,
expected=cls._REBOOT_TIMEOUT))
def run_once(self, host, job_repo_url=None):
"""Runs the test.
@param host: a host object representing the DUT
@param job_repo_url: URL to get the image.
@raise error.TestError if anything went wrong with setting up the test;
error.TestFail if any part of the test has failed.
"""
updater = autoupdate_utils.get_updater_from_repo_url(host, job_repo_url)
updater.update_stateful(clobber=True)
logging.info('Rebooting after performing update.')
self.reboot_with_timeout(host, 'update')
# TODO(sosa): Ideally we would be able to just use
# autotest.run_static_method to login/logout, however, this
# functionality is currently nested deep into the test logic. Once
# telemetry has replaced pyauto login and has been librarized, we
# should switch to using that code and not have to rely on running a
# client test to do what we want.
logging.info('Running sanity desktop login to see that we can '
'login and logout after performing an update.')
client_at = autotest.Autotest(host)
self.job.set_state('client_success', False)
client_at.run_test('login_LoginSuccess')
if not self.job.get_state('client_success'):
raise error.TestFail(
'Failed to login successfully after an update.')
logging.info('Rebooting the DUT after first login/logout.')
self.reboot_with_timeout(host, 'first login')