# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.update_engine import nebraska_wrapper
from autotest_lib.client.cros.update_engine import update_engine_test

class autoupdate_Backoff(update_engine_test.UpdateEngineTest):
    """
    Tests update_engine's backoff mechanism.

    When an update fails, update_engine will not allow another update to the
    same URL for a certain backoff period. The backoff period is stored in
    /var/lib/update_engine/prefs/backoff-expiry-time. It is stored as an
    integer representing the number of microseconds since 1/1/1601.

    By default, backoff is disabled on test images but by creating a
    'no-ignore-backoff' pref we can test it.

    """
    version = 1

    _BACKOFF_DISABLED = 'Resetting backoff expiry time as payload backoff is ' \
                        'disabled'
    _BACKOFF_ENABLED = 'Incrementing the backoff expiry time'
    _BACKOFF_ERROR = 'Updating payload state for error code: 40 (' \
                     'ErrorCode::kOmahaUpdateDeferredForBackoff)'
    _BACKOFF_EXPIRY_TIME_PREF = 'backoff-expiry-time'
    _NO_IGNORE_BACKOFF_PREF = 'no-ignore-backoff'


    def cleanup(self):
        """Cleans up the state and extra files this test created."""
        self._remove_update_engine_pref(self._NO_IGNORE_BACKOFF_PREF)
        self._remove_update_engine_pref(self._BACKOFF_EXPIRY_TIME_PREF)
        super(autoupdate_Backoff, self).cleanup()


    def run_once(self, payload_url, backoff):
        """
        Tests update_engine can do backoff.

        @param payload_url: The payload url.
        @param backoff: True if backoff is enabled.

        """
        utils.run(['touch',
                   os.path.join(self._UPDATE_ENGINE_PREFS_DIR,
                                self._NO_IGNORE_BACKOFF_PREF)],
                  ignore_status=True)

        with nebraska_wrapper.NebraskaWrapper(
            log_dir=self.resultsdir, payload_url=payload_url) as nebraska:
            # Only set one URL in the Nebraska response so we can test the
            # backoff functionality quicker.
            response_props = {'disable_payload_backoff': not backoff,
                              'failures_per_url': 1,
                              'critical_update': True}

            # Start the update.
            self._check_for_update(nebraska.get_update_url(**response_props),
                                   interactive=False)
            self._wait_for_progress(0.2)

            # Disable internet so the update fails.
            self._disable_internet()
            self._wait_for_update_to_fail()
            self._enable_internet()

            if backoff:
                self._check_update_engine_log_for_entry(self._BACKOFF_ENABLED,
                                                        raise_error=True)
                utils.run(['cat',
                           os.path.join(self._UPDATE_ENGINE_PREFS_DIR,
                                        self._BACKOFF_EXPIRY_TIME_PREF)])
                try:
                    self._check_for_update(
                        nebraska.get_update_url(**response_props),
                        interactive=False, wait_for_completion=True)
                except error.CmdError as e:
                    logging.info('Update failed as expected.')
                    logging.error(e)
                    self._check_update_engine_log_for_entry(self._BACKOFF_ERROR,
                                                            raise_error=True)
                    return

                raise error.TestFail('Second update attempt succeeded. It was '
                                     'supposed to have failed due to backoff.')
            else:
                self._check_update_engine_log_for_entry(self._BACKOFF_DISABLED,
                                                        raise_error=True)
                self._check_for_update(
                    nebraska.get_update_url(**response_props),
                    interactive=False)
                self._wait_for_update_to_complete()
