• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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