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