# Copyright 2011 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging

from autotest_lib.server.cros import vboot_constants as vboot
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest


class firmware_CorruptBothKernelAB(FirmwareTest):
    """
    Servo based both kernel A and B corruption test.

    This test requires a USB disk plugged-in, which contains a ChromeOS test
    image (built by "build_image --test"). On runtime, this test corrupts
    both kernel A and B. On next reboot, the kernel verification fails
    and enters recovery mode. This test then checks the success of the
    recovery boot.
    """
    version = 1
    NEEDS_SERVO_USB = True

    def initialize(self, host, cmdline_args, dev_mode=False):
        """Initialize the test"""
        super(firmware_CorruptBothKernelAB, self).initialize(host, cmdline_args)
        self.backup_kernel()
        self.backup_cgpt_attributes()
        self.switcher.setup_mode('dev' if dev_mode else 'normal')
        self.setup_usbkey(usbkey=True, host=False)
        self.setup_kernel('a')

    def cleanup(self):
        """Cleanup the test"""
        try:
            self.restore_cgpt_attributes()
            self.restore_kernel()
        except Exception as e:
            logging.error("Caught exception: %s", str(e))
        super(firmware_CorruptBothKernelAB, self).cleanup()

    def run_once(self, dev_mode=False):
        """Main test logic"""
        recovery_reason = (vboot.RECOVERY_REASON['DEP_RW_NO_DISK'],
                           vboot.RECOVERY_REASON['RW_NO_KERNEL'],
                           vboot.RECOVERY_REASON['RW_INVALID_OS'])

        time_now = self._now()

        logging.info("Corrupt kernel A and B.")
        self.check_state((self.check_root_part_on_non_recovery, 'a'))
        self.faft_client.kernel.corrupt_sig('a')
        self.faft_client.kernel.corrupt_sig('b')

        # Older devices (without BROKEN screen) didn't wait for removal in
        # dev mode. Make sure the USB key is not plugged in so they won't
        # start booting immediately and get interrupted by unplug/replug.
        self.servo.switch_usbkey('host')
        self.switcher.mode_aware_reboot(wait_for_dut_up=False)
        self.switcher.bypass_rec_mode()
        self.switcher.wait_for_client()

        logging.info("Expected recovery boot and restore the OS image.")
        self.check_state((self.checkers.crossystem_checker, {
                            'mainfw_type': 'recovery',
                            }))
        self.check_recovery_reason_since(time_now, recovery_reason)

        self.faft_client.kernel.restore_sig('a')
        self.faft_client.kernel.restore_sig('b')
        self.switcher.mode_aware_reboot()

        logging.info("Expected kernel A normal/dev boot.")
        self.check_state((self.check_root_part_on_non_recovery, 'a'))
