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 5 import logging 6 import os 7 8 from autotest_lib.client.bin import utils 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.cros.update_engine import nano_omaha_devserver 11 from autotest_lib.client.cros.update_engine import update_engine_test 12 13 class 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 utils.run('rm %s' % self._no_ignore_backoff, ignore_status=True) 39 utils.run('rm %s' % self._backoff_expiry_time, ignore_status=True) 40 super(autoupdate_Backoff, self).cleanup() 41 42 43 def run_once(self, image_url, image_size, sha256, backoff): 44 self._no_ignore_backoff = os.path.join( 45 self._UPDATE_ENGINE_PREFS_DIR, self._NO_IGNORE_BACKOFF_PREF) 46 self._backoff_expiry_time = os.path.join( 47 self._UPDATE_ENGINE_PREFS_DIR, self._BACKOFF_EXPIRY_TIME_PREF) 48 utils.run('touch %s' % self._no_ignore_backoff, ignore_status=True) 49 50 # Only set one URL in the omaha response so we can test the backoff 51 # functionality quicker. 52 self._omaha = nano_omaha_devserver.NanoOmahaDevserver( 53 backoff=backoff, num_urls=1) 54 self._omaha.set_image_params(image_url, image_size, sha256) 55 self._omaha.start() 56 57 # Start the update. 58 self._check_for_update(port=self._omaha.get_port(), interactive=False) 59 self._wait_for_progress(0.2) 60 61 # Disable internet so the update fails. 62 self._disable_internet() 63 self._wait_for_update_to_fail() 64 self._enable_internet() 65 66 if backoff: 67 self._check_update_engine_log_for_entry(self._BACKOFF_ENABLED, 68 raise_error=True) 69 utils.run('cat %s' % self._backoff_expiry_time) 70 try: 71 self._check_for_update(port=self._omaha.get_port(), 72 interactive=False, 73 wait_for_completion=True) 74 except error.CmdError as e: 75 logging.info('Update failed as expected.') 76 logging.error(e) 77 self._check_update_engine_log_for_entry(self._BACKOFF_ERROR, 78 raise_error=True) 79 return 80 81 raise error.TestFail('Second update attempt succeeded. It was ' 82 'supposed to have failed due to backoff.') 83 else: 84 self._check_update_engine_log_for_entry(self._BACKOFF_DISABLED, 85 raise_error=True) 86 self._check_for_update(port=self._omaha.get_port(), 87 interactive=False) 88 self._wait_for_update_to_complete() 89 90