Home | History | Annotate | Download | only in autoupdate_Backoff
      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