101 lines
4.2 KiB
Python
101 lines
4.2 KiB
Python
# 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 nebraska_wrapper
|
|
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):
|
|
"""Cleans up the state and extra files this test created."""
|
|
self._remove_update_engine_pref(self._NO_IGNORE_BACKOFF_PREF)
|
|
self._remove_update_engine_pref(self._BACKOFF_EXPIRY_TIME_PREF)
|
|
super(autoupdate_Backoff, self).cleanup()
|
|
|
|
|
|
def run_once(self, payload_url, backoff):
|
|
"""
|
|
Tests update_engine can do backoff.
|
|
|
|
@param payload_url: The payload url.
|
|
@param backoff: True if backoff is enabled.
|
|
|
|
"""
|
|
utils.run(['touch',
|
|
os.path.join(self._UPDATE_ENGINE_PREFS_DIR,
|
|
self._NO_IGNORE_BACKOFF_PREF)],
|
|
ignore_status=True)
|
|
|
|
with nebraska_wrapper.NebraskaWrapper(
|
|
log_dir=self.resultsdir, payload_url=payload_url) as nebraska:
|
|
# Only set one URL in the Nebraska response so we can test the
|
|
# backoff functionality quicker.
|
|
response_props = {'disable_payload_backoff': not backoff,
|
|
'failures_per_url': 1,
|
|
'critical_update': True}
|
|
|
|
# Start the update.
|
|
self._check_for_update(nebraska.get_update_url(**response_props),
|
|
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',
|
|
os.path.join(self._UPDATE_ENGINE_PREFS_DIR,
|
|
self._BACKOFF_EXPIRY_TIME_PREF)])
|
|
try:
|
|
self._check_for_update(
|
|
nebraska.get_update_url(**response_props),
|
|
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(
|
|
nebraska.get_update_url(**response_props),
|
|
interactive=False)
|
|
self._wait_for_update_to_complete()
|