# 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 random

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import kernel_utils
from autotest_lib.server.cros.update_engine import update_engine_test

class autoupdate_Interruptions(update_engine_test.UpdateEngineTest):
    """Ensures an update completes with multiple user interruptions."""
    version = 1

    def cleanup(self):
        self._save_extra_update_engine_logs(number_of_logs=2)
        super(autoupdate_Interruptions, self).cleanup()


    def run_once(self,
                 full_payload=True,
                 interrupt=None,
                 job_repo_url=None,
                 return_noupdate_starting=2):
        """
        Runs an update with interruptions from the user.

        @param full_payload: True for a full payload. False for delta.
        @param interrupt: The interrupt to perform: See _SUPPORTED_INTERRUPTS.
        @param job_repo_url: Used for debugging locally. This is used to figure
                             out the current build and the devserver to use.
                             The test will read this from a host argument
                             when run in the lab.
        @param return_noupdate_starting: (Number of times - 1) we want
                                         FakeOmaha to return an update before
                                         returning noupdate. 1 means never
                                         return noupdate. 2 means return
                                         noupdate after 1 update response.

        """
        if interrupt and interrupt not in self._SUPPORTED_INTERRUPTS:
            raise error.TestFail('Unknown interrupt type: %s' % interrupt)

        # Clear any previously started updates.
        self._remove_update_engine_pref(self._UPDATE_CHECK_RESPONSE_HASH)
        self._restart_update_engine(ignore_status=True)

        update_url = self.get_update_url_for_test(
                job_repo_url,
                full_payload=full_payload,
                return_noupdate_starting=return_noupdate_starting)
        chromeos_version = self._host.get_release_version()
        active, inactive = kernel_utils.get_kernel_state(self._host)
        # Choose a random downloaded progress to interrupt the update.
        progress = random.uniform(0.1, 0.6)
        logging.info('Progress when we will begin interruptions: %f', progress)

        # Login, start the update, logout
        self._run_client_test_and_check_result(
            'autoupdate_LoginStartUpdateLogout', update_url=update_url,
            progress_to_complete=progress,
            full_payload=full_payload,
            interrupt_network=interrupt == self._NETWORK_INTERRUPT)

        if interrupt in [self._REBOOT_INTERRUPT, self._SUSPEND_INTERRUPT]:
            if self._is_update_finished_downloading():
                raise error.TestFail(
                    'Update finished before %s interrupt started. Interrupt '
                    'was supposed to be at %f' % (interrupt, progress))
            self._wait_for_progress(progress)
            completed = self._get_update_progress()

            if interrupt == self._REBOOT_INTERRUPT:
                self._host.reboot()
                utils.poll_for_condition(self._get_update_engine_status,
                                         desc='update engine to start')
                self._check_for_update(update_url, critical_update=True,
                                       full_payload=full_payload)
            elif interrupt == self._SUSPEND_INTERRUPT:
                self._suspend_then_resume()

            if self._is_update_engine_idle():
                raise error.TestFail(
                    'The update was IDLE after interrupt. Last error: %s' %
                    self._get_last_error_string())
            if not self._update_continued_where_it_left_off(
                completed,
                reboot_interrupt=interrupt == self._REBOOT_INTERRUPT):
                raise error.TestFail('The update did not continue where it '
                                     'left off after interruption.')

        self._wait_for_update_to_complete()
        self._host.reboot()
        # Check that update engine is ready after reboot.
        utils.poll_for_condition(self._get_update_engine_status,
                                 desc='update engine to start')
        # Do a final update check with no_update=True to get post reboot event.
        self._check_for_update(update_url, no_update=True)

        # Verify the update was successful by checking hostlog and kernel.
        rootfs_hostlog, reboot_hostlog = self._create_hostlog_files()
        self.verify_update_events(chromeos_version, rootfs_hostlog)
        self.verify_update_events(chromeos_version, reboot_hostlog,
                                  chromeos_version)
        kernel_utils.verify_boot_expectations(inactive, host=self._host)
