| # Copyright 2018 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 os |
| |
| from autotest_lib.client.bin import utils |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.cros.update_engine import nano_omaha_devserver |
| from autotest_lib.client.cros.update_engine import update_engine_test |
| |
| class autoupdate_Backoff(update_engine_test.UpdateEngineTest): |
| """ |
| Tests update_engine's backoff mechanism. |
| |
| When an update fails, update_engine will not allow another update to the |
| same URL for a certain backoff period. The backoff period is stored in |
| /var/lib/update_engine/prefs/backoff-expiry-time. It is stored as an |
| integer representing the number of microseconds since 1/1/1601. |
| |
| By default, backoff is disabled on test images but by creating a |
| 'no-ignore-backoff' pref we can test it. |
| |
| """ |
| version = 1 |
| |
| _BACKOFF_DISABLED = 'Resetting backoff expiry time as payload backoff is ' \ |
| 'disabled' |
| _BACKOFF_ENABLED = 'Incrementing the backoff expiry time' |
| _BACKOFF_ERROR = 'Updating payload state for error code: 40 (' \ |
| 'ErrorCode::kOmahaUpdateDeferredForBackoff)' |
| _BACKOFF_EXPIRY_TIME_PREF = 'backoff-expiry-time' |
| _NO_IGNORE_BACKOFF_PREF = 'no-ignore-backoff' |
| |
| |
| def cleanup(self): |
| utils.run('rm %s' % self._no_ignore_backoff, ignore_status=True) |
| utils.run('rm %s' % self._backoff_expiry_time, ignore_status=True) |
| super(autoupdate_Backoff, self).cleanup() |
| |
| |
| def run_once(self, image_url, image_size, sha256, backoff): |
| self._no_ignore_backoff = os.path.join( |
| self._UPDATE_ENGINE_PREFS_DIR, self._NO_IGNORE_BACKOFF_PREF) |
| self._backoff_expiry_time = os.path.join( |
| self._UPDATE_ENGINE_PREFS_DIR, self._BACKOFF_EXPIRY_TIME_PREF) |
| utils.run('touch %s' % self._no_ignore_backoff, ignore_status=True) |
| |
| # Only set one URL in the omaha response so we can test the backoff |
| # functionality quicker. |
| self._omaha = nano_omaha_devserver.NanoOmahaDevserver( |
| backoff=backoff, num_urls=1) |
| self._omaha.set_image_params(image_url, image_size, sha256) |
| self._omaha.start() |
| |
| # Start the update. |
| self._check_for_update(port=self._omaha.get_port(), interactive=False) |
| self._wait_for_progress(0.2) |
| |
| # Disable internet so the update fails. |
| self._disable_internet() |
| self._wait_for_update_to_fail() |
| self._enable_internet() |
| |
| if backoff: |
| self._check_update_engine_log_for_entry(self._BACKOFF_ENABLED, |
| raise_error=True) |
| utils.run('cat %s' % self._backoff_expiry_time) |
| try: |
| self._check_for_update(port=self._omaha.get_port(), |
| interactive=False, |
| wait_for_completion=True) |
| except error.CmdError as e: |
| logging.info('Update failed as expected.') |
| logging.error(e) |
| self._check_update_engine_log_for_entry(self._BACKOFF_ERROR, |
| raise_error=True) |
| return |
| |
| raise error.TestFail('Second update attempt succeeded. It was ' |
| 'supposed to have failed due to backoff.') |
| else: |
| self._check_update_engine_log_for_entry(self._BACKOFF_DISABLED, |
| raise_error=True) |
| self._check_for_update(port=self._omaha.get_port(), |
| interactive=False) |
| self._wait_for_update_to_complete() |
| |