1# Copyright (c) 2011 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
6
7from autotest_lib.server.cros import vboot_constants as vboot
8from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
9
10
11class firmware_RecoveryButton(FirmwareTest):
12    """
13    Servo based recovery button test.
14
15    This test requires a USB disk plugged-in, which contains a Chrome OS test
16    image (built by "build_image --test"). On runtime, this test emulates
17    recovery button pressed and reboots. It then triggers recovery mode by
18    unplugging and plugging in the USB disk and checks success of it.
19    """
20    version = 1
21
22    def ensure_normal_boot(self):
23        """Ensure normal mode boot this time.
24
25        If not, it may be a test failure during step 2, try to recover to
26        normal mode by setting no recovery mode and rebooting the machine.
27        """
28        if not self.checkers.crossystem_checker(
29                {'mainfw_type': ('normal', 'developer')}):
30            self.servo.disable_recovery_mode()
31            self.switcher.mode_aware_reboot()
32
33    def initialize(self, host, cmdline_args, dev_mode=False, ec_wp=None):
34        super(firmware_RecoveryButton, self).initialize(host, cmdline_args,
35                                                        ec_wp=ec_wp)
36        self.switcher.setup_mode('dev' if dev_mode else 'normal')
37        self.setup_usbkey(usbkey=True, host=False)
38
39    def cleanup(self):
40        self.ensure_normal_boot()
41        super(firmware_RecoveryButton, self).cleanup()
42
43    def run_once(self, dev_mode=False):
44        is_jetstream = (self.faft_config.mode_switcher_type ==
45                        'jetstream_switcher')
46        logging.info("Switch to recovery mode and reboot.")
47        self.check_state((self.checkers.crossystem_checker, {
48                    'mainfw_type': 'developer' if dev_mode else 'normal',
49                    }))
50        self.switcher.reboot_to_mode(to_mode='rec',
51                                     from_mode='dev' if dev_mode else 'normal')
52
53        logging.info("Expected recovery boot and reboot.")
54        self.check_state((self.checkers.crossystem_checker, {
55                    'mainfw_type': 'recovery',
56                    'recovery_reason': vboot.RECOVERY_REASON['RO_MANUAL'],
57                    }))
58        self.switcher.mode_aware_reboot()
59
60        logging.info("Expected normal/dev boot.")
61        self.check_state((self.checkers.crossystem_checker, {
62                    'mainfw_type': 'developer' if dev_mode and not is_jetstream
63                                    else 'normal',
64                    }))
65