1# Lint as: python2, python3 2# Copyright 2018 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import os 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.cros.update_engine import nebraska_wrapper 12from autotest_lib.client.cros.update_engine import update_engine_test 13 14class autoupdate_Backoff(update_engine_test.UpdateEngineTest): 15 """ 16 Tests update_engine's backoff mechanism. 17 18 When an update fails, update_engine will not allow another update to the 19 same URL for a certain backoff period. The backoff period is stored in 20 /var/lib/update_engine/prefs/backoff-expiry-time. It is stored as an 21 integer representing the number of microseconds since 1/1/1601. 22 23 By default, backoff is disabled on test images but by creating a 24 'no-ignore-backoff' pref we can test it. 25 26 """ 27 version = 1 28 29 _BACKOFF_DISABLED = 'Resetting backoff expiry time as payload backoff is ' \ 30 'disabled' 31 _BACKOFF_ENABLED = 'Incrementing the backoff expiry time' 32 _BACKOFF_ERROR = 'Updating payload state for error code: 40 (' \ 33 'ErrorCode::kOmahaUpdateDeferredForBackoff)' 34 _BACKOFF_EXPIRY_TIME_PREF = 'backoff-expiry-time' 35 _NO_IGNORE_BACKOFF_PREF = 'no-ignore-backoff' 36 37 38 def cleanup(self): 39 """Cleans up the state and extra files this test created.""" 40 self._remove_update_engine_pref(self._NO_IGNORE_BACKOFF_PREF) 41 self._remove_update_engine_pref(self._BACKOFF_EXPIRY_TIME_PREF) 42 super(autoupdate_Backoff, self).cleanup() 43 44 45 def run_once(self, payload_url, backoff): 46 """ 47 Tests update_engine can do backoff. 48 49 @param payload_url: The payload url. 50 @param backoff: True if backoff is enabled. 51 52 """ 53 utils.run(['touch', 54 os.path.join(self._UPDATE_ENGINE_PREFS_DIR, 55 self._NO_IGNORE_BACKOFF_PREF)], 56 ignore_status=True) 57 58 with nebraska_wrapper.NebraskaWrapper( 59 log_dir=self.resultsdir, payload_url=payload_url) as nebraska: 60 # Only set one URL in the Nebraska response so we can test the 61 # backoff functionality quicker. 62 response_props = {'disable_payload_backoff': not backoff, 63 'failures_per_url': 1, 64 'critical_update': True} 65 66 # Start the update. 67 self._check_for_update(nebraska.get_update_url(**response_props), 68 interactive=False) 69 self._wait_for_progress(0.2) 70 71 # Disable internet so the update fails. 72 self._disable_internet() 73 self._wait_for_update_to_fail() 74 self._enable_internet() 75 76 if backoff: 77 self._check_update_engine_log_for_entry(self._BACKOFF_ENABLED, 78 raise_error=True) 79 utils.run(['cat', 80 os.path.join(self._UPDATE_ENGINE_PREFS_DIR, 81 self._BACKOFF_EXPIRY_TIME_PREF)]) 82 try: 83 self._check_for_update( 84 nebraska.get_update_url(**response_props), 85 interactive=False, wait_for_completion=True) 86 except error.CmdError as e: 87 logging.info('Update failed as expected.') 88 logging.error(e) 89 self._check_update_engine_log_for_entry(self._BACKOFF_ERROR, 90 raise_error=True) 91 return 92 93 raise error.TestFail('Second update attempt succeeded. It was ' 94 'supposed to have failed due to backoff.') 95 else: 96 self._check_update_engine_log_for_entry(self._BACKOFF_DISABLED, 97 raise_error=True) 98 self._check_for_update( 99 nebraska.get_update_url(**response_props), 100 interactive=False) 101 self._wait_for_update_to_complete() 102